implement Material You
This commit is contained in:
parent
760c9639e2
commit
eb4751f953
|
@ -90,7 +90,7 @@ dependencies {
|
||||||
implementation("androidx.compose.material:material-icons-core:$composeVersion")
|
implementation("androidx.compose.material:material-icons-core:$composeVersion")
|
||||||
implementation("androidx.compose.material:material-icons-extended:$composeVersion")
|
implementation("androidx.compose.material:material-icons-extended:$composeVersion")
|
||||||
implementation("androidx.compose.material:material:$composeVersion")
|
implementation("androidx.compose.material:material:$composeVersion")
|
||||||
implementation("androidx.compose.material:material:$composeVersion")
|
implementation("androidx.compose.material3:material3:1.0.0-alpha01")
|
||||||
implementation("androidx.compose.runtime:runtime-livedata:$composeVersion")
|
implementation("androidx.compose.runtime:runtime-livedata:$composeVersion")
|
||||||
implementation("androidx.compose.ui:ui-tooling:$composeVersion")
|
implementation("androidx.compose.ui:ui-tooling:$composeVersion")
|
||||||
implementation("androidx.compose.ui:ui-util:$composeVersion")
|
implementation("androidx.compose.ui:ui-util:$composeVersion")
|
||||||
|
|
|
@ -7,27 +7,17 @@ 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.animation.*
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.material.*
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
import androidx.compose.material.icons.filled.ArrowBackIos
|
import androidx.compose.runtime.SideEffect
|
||||||
import androidx.compose.material.icons.filled.MoreVert
|
|
||||||
import androidx.compose.runtime.*
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.github.zsoltk.compose.backpress.BackPressHandler
|
import com.github.zsoltk.compose.backpress.BackPressHandler
|
||||||
import com.github.zsoltk.compose.backpress.LocalBackPressHandler
|
import com.github.zsoltk.compose.backpress.LocalBackPressHandler
|
||||||
import com.github.zsoltk.compose.router.Router
|
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.ui.component.color.managerAnimatedColor
|
|
||||||
import com.vanced.manager.ui.component.color.managerSurfaceColor
|
import com.vanced.manager.ui.component.color.managerSurfaceColor
|
||||||
import com.vanced.manager.ui.component.color.managerTextColor
|
|
||||||
import com.vanced.manager.ui.component.menu.ManagerDropdownMenuItem
|
|
||||||
import com.vanced.manager.ui.component.text.ToolbarTitleText
|
|
||||||
import com.vanced.manager.ui.resources.managerString
|
|
||||||
import com.vanced.manager.ui.screens.*
|
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
|
||||||
|
@ -53,14 +43,15 @@ class MainActivity : ComponentActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalAnimationApi::class)
|
@OptIn(
|
||||||
|
ExperimentalAnimationApi::class,
|
||||||
|
ExperimentalMaterial3Api::class,
|
||||||
|
ExperimentalFoundationApi::class
|
||||||
|
)
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContent {
|
setContent {
|
||||||
ManagerTheme {
|
ManagerTheme {
|
||||||
var isMenuExpanded by remember { mutableStateOf(false) }
|
|
||||||
var currentScreen by remember { mutableStateOf<Screen>(Screen.Home) }
|
|
||||||
|
|
||||||
val surfaceColor = managerSurfaceColor()
|
val surfaceColor = managerSurfaceColor()
|
||||||
|
|
||||||
val isDark = isDark()
|
val isDark = isDark()
|
||||||
|
@ -78,98 +69,62 @@ class MainActivity : ComponentActivity() {
|
||||||
LocalBackPressHandler provides backPressHandler
|
LocalBackPressHandler provides backPressHandler
|
||||||
) {
|
) {
|
||||||
Router<Screen>("VancedManager", Screen.Home) { backStack ->
|
Router<Screen>("VancedManager", Screen.Home) { backStack ->
|
||||||
val screen = backStack.last()
|
when (val screen = backStack.last()) {
|
||||||
currentScreen = screen
|
is Screen.Home -> {
|
||||||
|
HomeLayout(
|
||||||
|
onToolbarScreenSelected = {
|
||||||
|
backStack.push(it)
|
||||||
|
},
|
||||||
|
onAppInstallPress = { appName, appVersions, installationOptions ->
|
||||||
|
if (installationOptions != null) {
|
||||||
|
backStack.push(
|
||||||
|
Screen.InstallPreferences(
|
||||||
|
appName,
|
||||||
|
appVersions,
|
||||||
|
installationOptions
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
backStack.push(Screen.Install(appName, appVersions))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
is Screen.Settings -> {
|
||||||
|
SettingsLayout(
|
||||||
|
onToolbarBackButtonClick = {
|
||||||
|
backStack.pop()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
is Screen.About -> {
|
||||||
|
AboutLayout(
|
||||||
|
onToolbarBackButtonClick = {
|
||||||
|
backStack.pop()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
is Screen.Logs -> {
|
||||||
|
|
||||||
Scaffold(
|
}
|
||||||
topBar = {
|
is Screen.InstallPreferences -> {
|
||||||
TopAppBar(
|
InstallPreferencesScreen(
|
||||||
title = {
|
installationOptions = screen.appInstallationOptions,
|
||||||
ToolbarTitleText(
|
onToolbarBackButtonClick = {
|
||||||
text = managerString(
|
backStack.pop()
|
||||||
stringId = currentScreen.displayName
|
},
|
||||||
|
onDoneClick = {
|
||||||
|
backStack.push(
|
||||||
|
Screen.Install(
|
||||||
|
screen.appName,
|
||||||
|
screen.appVersions
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
},
|
}
|
||||||
backgroundColor = managerAnimatedColor(color = MaterialTheme.colors.surface),
|
|
||||||
actions = {
|
|
||||||
if (currentScreen is Screen.Home) {
|
|
||||||
IconButton(
|
|
||||||
onClick = { isMenuExpanded = true }
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Default.MoreVert,
|
|
||||||
contentDescription = null,
|
|
||||||
tint = managerTextColor()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
DropdownMenu(
|
|
||||||
expanded = isMenuExpanded,
|
|
||||||
onDismissRequest = {
|
|
||||||
isMenuExpanded = false
|
|
||||||
},
|
|
||||||
modifier = Modifier.background(MaterialTheme.colors.surface),
|
|
||||||
) {
|
|
||||||
ManagerDropdownMenuItem(
|
|
||||||
title = stringResource(id = Screen.Settings.displayName)
|
|
||||||
) {
|
|
||||||
isMenuExpanded = false
|
|
||||||
backStack.push(Screen.Settings)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
navigationIcon = if (currentScreen !is Screen.Home) {
|
|
||||||
{
|
|
||||||
IconButton(onClick = {
|
|
||||||
backStack.pop()
|
|
||||||
}) {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Default.ArrowBackIos,
|
|
||||||
contentDescription = null,
|
|
||||||
tint = managerTextColor()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else null,
|
|
||||||
elevation = 0.dp
|
|
||||||
)
|
)
|
||||||
},
|
}
|
||||||
backgroundColor = surfaceColor
|
is Screen.Install -> {
|
||||||
) {
|
InstallScreen(screen.appName, screen.appVersions)
|
||||||
when (screen) {
|
|
||||||
is Screen.Home -> {
|
|
||||||
HomeLayout(
|
|
||||||
onAppInstallPress = { appName, appVersions, installationOptions ->
|
|
||||||
if (installationOptions != null) {
|
|
||||||
backStack.push(Screen.InstallPreferences(appName, appVersions, installationOptions))
|
|
||||||
} else {
|
|
||||||
backStack.push(Screen.Install(appName, appVersions))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
is Screen.Settings -> {
|
|
||||||
SettingsLayout()
|
|
||||||
}
|
|
||||||
is Screen.About -> {
|
|
||||||
AboutLayout()
|
|
||||||
}
|
|
||||||
is Screen.Logs -> {
|
|
||||||
|
|
||||||
}
|
|
||||||
is Screen.InstallPreferences -> {
|
|
||||||
InstallPreferencesScreen(
|
|
||||||
installationOptions = screen.appInstallationOptions,
|
|
||||||
onDoneClick = {
|
|
||||||
backStack.push(Screen.Install(screen.appName, screen.appVersions))
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
is Screen.Install -> {
|
|
||||||
InstallScreen(screen.appName, screen.appVersions)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,8 @@ import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.material.Icon
|
|
||||||
import androidx.compose.material.ripple.rememberRipple
|
import androidx.compose.material.ripple.rememberRipple
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
|
@ -15,7 +15,7 @@ import androidx.compose.ui.semantics.Role
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun IconButton(
|
fun ManagerIconButton(
|
||||||
icon: ImageVector,
|
icon: ImageVector,
|
||||||
contentDescription: String,
|
contentDescription: String,
|
||||||
onClick: () -> Unit
|
onClick: () -> Unit
|
||||||
|
|
|
@ -2,15 +2,15 @@ package com.vanced.manager.ui.component.button
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.RowScope
|
import androidx.compose.foundation.layout.RowScope
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.material.Button
|
import androidx.compose.material3.Button
|
||||||
import androidx.compose.material.ButtonDefaults
|
import androidx.compose.material3.ButtonDefaults
|
||||||
import androidx.compose.material.MaterialTheme
|
|
||||||
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 androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.luminance
|
import androidx.compose.ui.graphics.luminance
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.vanced.manager.ui.component.color.managerAccentColor
|
import com.vanced.manager.ui.component.color.managerAccentColor
|
||||||
|
import com.vanced.manager.ui.theme.MediumShape
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ManagerThemedButton(
|
fun ManagerThemedButton(
|
||||||
|
@ -22,16 +22,16 @@ fun ManagerThemedButton(
|
||||||
Button(
|
Button(
|
||||||
modifier = modifier.fillMaxWidth(),
|
modifier = modifier.fillMaxWidth(),
|
||||||
onClick = onClick,
|
onClick = onClick,
|
||||||
shape = MaterialTheme.shapes.medium,
|
shape = MediumShape,
|
||||||
colors = ButtonDefaults.buttonColors(
|
colors = ButtonDefaults.buttonColors(
|
||||||
backgroundColor = backgroundColor,
|
containerColor = backgroundColor,
|
||||||
contentColor =
|
contentColor =
|
||||||
if (backgroundColor.luminance() > 0.7)
|
if (backgroundColor.luminance() > 0.7)
|
||||||
Color.Black
|
Color.Black
|
||||||
else
|
else
|
||||||
Color.White
|
Color.White
|
||||||
),
|
),
|
||||||
elevation = ButtonDefaults.elevation(0.dp, 0.dp, 0.dp)
|
elevation = ButtonDefaults.elevatedButtonElevation(0.dp, 0.dp, 0.dp, 0.dp)
|
||||||
) {
|
) {
|
||||||
content()
|
content()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +1,31 @@
|
||||||
package com.vanced.manager.ui.component.card
|
package com.vanced.manager.ui.component.card
|
||||||
|
|
||||||
import androidx.compose.material.Card
|
|
||||||
import androidx.compose.material.ExperimentalMaterialApi
|
import androidx.compose.material.ExperimentalMaterialApi
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Surface
|
||||||
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 androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.Shape
|
import androidx.compose.ui.graphics.Shape
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.vanced.manager.ui.theme.MediumShape
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ManagerCard(
|
fun ManagerCard(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
shape: Shape = MaterialTheme.shapes.medium,
|
shape: Shape = MediumShape,
|
||||||
backgroundColor: Color = MaterialTheme.colors.surface,
|
backgroundColor: Color = MaterialTheme.colorScheme.surface,
|
||||||
|
tonalElevation: Dp = 0.dp,
|
||||||
|
shadowElevation: Dp = 0.dp,
|
||||||
content: @Composable () -> Unit,
|
content: @Composable () -> Unit,
|
||||||
) {
|
) {
|
||||||
Card(
|
Surface(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
shape = shape,
|
shape = shape,
|
||||||
backgroundColor = backgroundColor,
|
color = backgroundColor,
|
||||||
elevation = 0.dp,
|
shadowElevation = shadowElevation,
|
||||||
|
tonalElevation = tonalElevation,
|
||||||
content = content
|
content = content
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -29,17 +34,20 @@ fun ManagerCard(
|
||||||
@Composable
|
@Composable
|
||||||
fun ManagerCard(
|
fun ManagerCard(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
shape: Shape = MaterialTheme.shapes.medium,
|
shape: Shape = MediumShape,
|
||||||
backgroundColor: Color = MaterialTheme.colors.surface,
|
backgroundColor: Color = MaterialTheme.colorScheme.surface,
|
||||||
|
tonalElevation: Dp = 0.dp,
|
||||||
|
shadowElevation: Dp = 0.dp,
|
||||||
onClick: () -> Unit,
|
onClick: () -> Unit,
|
||||||
content: @Composable () -> Unit,
|
content: @Composable () -> Unit,
|
||||||
) {
|
) {
|
||||||
Card(
|
Surface(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
shape = shape,
|
shape = shape,
|
||||||
backgroundColor = backgroundColor,
|
color = backgroundColor,
|
||||||
elevation = 0.dp,
|
shadowElevation = shadowElevation,
|
||||||
content = content,
|
tonalElevation = tonalElevation,
|
||||||
onClick = onClick
|
onClick = onClick,
|
||||||
|
content = content
|
||||||
)
|
)
|
||||||
}
|
}
|
|
@ -1,25 +1,22 @@
|
||||||
package com.vanced.manager.ui.component.card
|
package com.vanced.manager.ui.component.card
|
||||||
|
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.compose.foundation.Canvas
|
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.material.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material.Text
|
|
||||||
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.geometry.Offset
|
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import com.github.zsoltk.compose.backpress.LocalBackPressHandler
|
||||||
import com.vanced.manager.ui.component.color.ThemedItemContentColorProvider
|
import com.vanced.manager.ui.component.text.ManagerText
|
||||||
import com.vanced.manager.ui.component.color.managerAccentColor
|
import com.vanced.manager.ui.util.DefaultContentPaddingHorizontal
|
||||||
|
import com.vanced.manager.ui.util.DefaultContentPaddingVertical
|
||||||
|
|
||||||
private val cardModifier = Modifier.sizeIn(
|
private val cardModifier = Modifier.sizeIn(
|
||||||
minHeight = 95.dp,
|
minHeight = 100.dp,
|
||||||
minWidth = 95.dp
|
minWidth = 100.dp
|
||||||
)
|
)
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
@ -27,7 +24,8 @@ fun ManagerItemCard(
|
||||||
title: String,
|
title: String,
|
||||||
@DrawableRes icon: Int? = null
|
@DrawableRes icon: Int? = null
|
||||||
) {
|
) {
|
||||||
ManagerThemedCard(
|
LocalBackPressHandler.current.handle()
|
||||||
|
ManagerCard(
|
||||||
modifier = cardModifier,
|
modifier = cardModifier,
|
||||||
) {
|
) {
|
||||||
ManagerItemCardContent(title, icon)
|
ManagerItemCardContent(title, icon)
|
||||||
|
@ -35,12 +33,12 @@ fun ManagerItemCard(
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ManagerClickableItemCard(
|
fun ManagerItemCard(
|
||||||
title: String,
|
title: String,
|
||||||
@DrawableRes icon: Int? = null,
|
@DrawableRes icon: Int? = null,
|
||||||
onClick: () -> Unit
|
onClick: () -> Unit
|
||||||
) {
|
) {
|
||||||
ManagerClickableThemedCard(
|
ManagerTonalCard(
|
||||||
modifier = cardModifier,
|
modifier = cardModifier,
|
||||||
onClick = onClick
|
onClick = onClick
|
||||||
) {
|
) {
|
||||||
|
@ -53,34 +51,25 @@ private fun ManagerItemCardContent(
|
||||||
title: String,
|
title: String,
|
||||||
@DrawableRes icon: Int? = null,
|
@DrawableRes icon: Int? = null,
|
||||||
) {
|
) {
|
||||||
val accentColor = managerAccentColor()
|
Column(
|
||||||
val circleOffset = 32.dp.value
|
modifier = Modifier.padding(
|
||||||
Canvas(modifier = Modifier.requiredSize(72.dp)) {
|
horizontal = DefaultContentPaddingHorizontal,
|
||||||
drawCircle(
|
vertical = DefaultContentPaddingVertical
|
||||||
color = accentColor,
|
),
|
||||||
center = Offset(circleOffset, circleOffset)
|
horizontalAlignment = Alignment.Start,
|
||||||
)
|
verticalArrangement = Arrangement.SpaceBetween
|
||||||
}
|
|
||||||
Box(
|
|
||||||
modifier = Modifier.padding(12.dp)
|
|
||||||
) {
|
) {
|
||||||
if (icon != null) {
|
if (icon != null) {
|
||||||
ThemedItemContentColorProvider {
|
Icon(
|
||||||
Icon(
|
modifier = Modifier
|
||||||
modifier = Modifier
|
.size(36.dp),
|
||||||
.size(28.dp)
|
painter = painterResource(id = icon),
|
||||||
.align(Alignment.TopStart),
|
contentDescription = title,
|
||||||
painter = painterResource(id = icon),
|
)
|
||||||
contentDescription = title
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Text(
|
ManagerText(
|
||||||
modifier = Modifier.align(Alignment.BottomStart),
|
|
||||||
text = title,
|
text = title,
|
||||||
fontSize = 12.sp,
|
textStyle = MaterialTheme.typography.labelLarge
|
||||||
fontWeight = FontWeight.Medium,
|
|
||||||
color = MaterialTheme.colors.onSurface
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -20,7 +20,7 @@ fun ManagerLinkCard(
|
||||||
val uri = remember { Uri.parse(link) }
|
val uri = remember { Uri.parse(link) }
|
||||||
val intent = remember { Intent(Intent.ACTION_VIEW, uri) }
|
val intent = remember { Intent(Intent.ACTION_VIEW, uri) }
|
||||||
val useCustomTabs by useCustomTabsPref
|
val useCustomTabs by useCustomTabsPref
|
||||||
ManagerClickableItemCard(
|
ManagerItemCard(
|
||||||
title = title,
|
title = title,
|
||||||
icon = icon
|
icon = icon
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -1,38 +1,37 @@
|
||||||
package com.vanced.manager.ui.component.card
|
package com.vanced.manager.ui.component.card
|
||||||
|
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Shape
|
import androidx.compose.ui.graphics.Shape
|
||||||
import com.vanced.manager.ui.component.color.managerThemedCardColor
|
import com.vanced.manager.ui.theme.MediumShape
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ManagerThemedCard(
|
fun ManagerContainerCard(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
shape: Shape = MaterialTheme.shapes.medium,
|
shape: Shape = MediumShape,
|
||||||
content: @Composable () -> Unit,
|
content: @Composable () -> Unit,
|
||||||
) {
|
) {
|
||||||
ManagerCard(
|
ManagerCard(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
shape = shape,
|
shape = shape,
|
||||||
backgroundColor = managerThemedCardColor(),
|
backgroundColor = MaterialTheme.colorScheme.primaryContainer,
|
||||||
content = content
|
content = content
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ManagerClickableThemedCard(
|
fun ManagerContainerCard(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
shape: Shape = MaterialTheme.shapes.medium,
|
shape: Shape = MediumShape,
|
||||||
onClick: () -> Unit,
|
onClick: () -> Unit,
|
||||||
content: @Composable () -> Unit,
|
content: @Composable () -> Unit,
|
||||||
) {
|
) {
|
||||||
ManagerCard(
|
ManagerCard(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
shape = shape,
|
shape = shape,
|
||||||
backgroundColor = managerThemedCardColor(),
|
backgroundColor = MaterialTheme.colorScheme.primaryContainer,
|
||||||
onClick = onClick,
|
onClick = onClick,
|
||||||
) {
|
content = content,
|
||||||
content()
|
)
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
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
|
||||||
|
)
|
||||||
|
}
|
|
@ -3,33 +3,37 @@ package com.vanced.manager.ui.component.checkbox
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import androidx.compose.foundation.layout.BoxWithConstraints
|
import androidx.compose.foundation.layout.BoxWithConstraints
|
||||||
import androidx.compose.foundation.layout.requiredSizeIn
|
import androidx.compose.foundation.layout.requiredSizeIn
|
||||||
import androidx.compose.material.Icon
|
|
||||||
import androidx.compose.material.MaterialTheme
|
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.rounded.Close
|
import androidx.compose.material.icons.rounded.Close
|
||||||
import androidx.compose.material.icons.rounded.Done
|
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.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.Shape
|
import androidx.compose.ui.graphics.Shape
|
||||||
import com.vanced.manager.ui.component.card.ManagerCard
|
import com.vanced.manager.ui.component.card.ManagerCard
|
||||||
import com.vanced.manager.ui.component.color.contentColorForColor
|
|
||||||
import com.vanced.manager.ui.component.color.managerAccentColor
|
|
||||||
import com.vanced.manager.ui.component.color.managerAnimatedColor
|
import com.vanced.manager.ui.component.color.managerAnimatedColor
|
||||||
import com.vanced.manager.ui.component.color.managerThemedCardColor
|
import com.vanced.manager.ui.theme.MediumShape
|
||||||
|
|
||||||
@SuppressLint("UnusedTransitionTargetStateParameter")
|
@SuppressLint("UnusedTransitionTargetStateParameter")
|
||||||
@Composable
|
@Composable
|
||||||
fun ManagerCheckbox(
|
fun ManagerCheckbox(
|
||||||
modifier: Modifier,
|
modifier: Modifier,
|
||||||
isChecked: Boolean,
|
isChecked: Boolean,
|
||||||
shape: Shape = MaterialTheme.shapes.medium,
|
shape: Shape = MediumShape,
|
||||||
onCheckedChange: (isChecked: Boolean) -> Unit
|
onCheckedChange: (isChecked: Boolean) -> Unit
|
||||||
) {
|
) {
|
||||||
val cardColor =
|
val cardColor =
|
||||||
managerAnimatedColor(if (isChecked) managerAccentColor() else managerThemedCardColor())
|
managerAnimatedColor(if (isChecked) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.primaryContainer)
|
||||||
val iconTint =
|
val iconTint =
|
||||||
managerAnimatedColor(if (isChecked) contentColorForColor(cardColor) else managerAccentColor())
|
managerAnimatedColor(
|
||||||
|
if (isChecked)
|
||||||
|
contentColorFor(MaterialTheme.colorScheme.primary)
|
||||||
|
else
|
||||||
|
contentColorFor(MaterialTheme.colorScheme.primaryContainer)
|
||||||
|
)
|
||||||
|
|
||||||
ManagerCard(
|
ManagerCard(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.vanced.manager.ui.component.color
|
package com.vanced.manager.ui.component.color
|
||||||
|
|
||||||
import androidx.compose.material.LocalContentColor
|
import androidx.compose.material3.LocalContentColor
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ package com.vanced.manager.ui.component.color
|
||||||
|
|
||||||
import androidx.compose.animation.animateColorAsState
|
import androidx.compose.animation.animateColorAsState
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.luminance
|
import androidx.compose.ui.graphics.luminance
|
||||||
|
@ -25,10 +25,10 @@ fun managerAccentColor(): Color {
|
||||||
fun managerThemedCardColor() = managerAccentColor().copy(alpha = 0.27f)
|
fun managerThemedCardColor() = managerAccentColor().copy(alpha = 0.27f)
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun managerTextColor(): Color = managerAnimatedColor(color = MaterialTheme.colors.onSurface)
|
fun managerTextColor(): Color = managerAnimatedColor(color = MaterialTheme.colorScheme.onSurface)
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun managerSurfaceColor(): Color = managerAnimatedColor(color = MaterialTheme.colors.surface)
|
fun managerSurfaceColor(): Color = managerAnimatedColor(color = MaterialTheme.colorScheme.surface)
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun managerAnimatedColor(
|
fun managerAnimatedColor(
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
package com.vanced.manager.ui.component.dialog
|
package com.vanced.manager.ui.component.dialog
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material3.AlertDialog
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.window.Dialog
|
import androidx.compose.ui.window.Dialog
|
||||||
import com.vanced.manager.ui.component.card.ManagerCard
|
import com.vanced.manager.ui.component.card.ManagerCard
|
||||||
import com.vanced.manager.ui.component.text.ManagerText
|
import com.vanced.manager.ui.component.text.ManagerText
|
||||||
|
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
|
||||||
|
|
||||||
|
@ -15,45 +18,25 @@ import com.vanced.manager.ui.util.DefaultContentPaddingVertical
|
||||||
fun ManagerDialog(
|
fun ManagerDialog(
|
||||||
title: String,
|
title: String,
|
||||||
onDismissRequest: () -> Unit,
|
onDismissRequest: () -> Unit,
|
||||||
buttons: @Composable ColumnScope.() -> Unit,
|
confirmButton: @Composable () -> Unit,
|
||||||
content: @Composable ColumnScope.() -> Unit,
|
modifier: Modifier = Modifier,
|
||||||
|
dismissButton: @Composable (() -> Unit)? = null,
|
||||||
|
icon: @Composable (() -> Unit)? = null,
|
||||||
|
content: @Composable () -> Unit,
|
||||||
) {
|
) {
|
||||||
ManagerDialog(
|
AlertDialog(
|
||||||
|
modifier = modifier,
|
||||||
title = {
|
title = {
|
||||||
ManagerText(
|
ManagerText(
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth(),
|
|
||||||
textStyle = MaterialTheme.typography.h2,
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
text = title
|
text = title
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
text = content,
|
||||||
onDismissRequest = onDismissRequest,
|
onDismissRequest = onDismissRequest,
|
||||||
buttons = buttons,
|
confirmButton = confirmButton,
|
||||||
content = content
|
dismissButton = dismissButton,
|
||||||
|
icon = icon,
|
||||||
|
shape = LargeShape,
|
||||||
|
tonalElevation = 2.dp,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ManagerDialog(
|
|
||||||
title: @Composable ColumnScope.() -> Unit,
|
|
||||||
onDismissRequest: () -> Unit,
|
|
||||||
buttons: @Composable ColumnScope.() -> Unit,
|
|
||||||
content: @Composable ColumnScope.() -> Unit,
|
|
||||||
) {
|
|
||||||
Dialog(
|
|
||||||
onDismissRequest = onDismissRequest,
|
|
||||||
content = {
|
|
||||||
ManagerCard {
|
|
||||||
Column(
|
|
||||||
modifier = Modifier.padding(DefaultContentPaddingHorizontal),
|
|
||||||
verticalArrangement = Arrangement.spacedBy(DefaultContentPaddingVertical)
|
|
||||||
) {
|
|
||||||
title()
|
|
||||||
content()
|
|
||||||
buttons()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -8,19 +8,15 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
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 ManagerLazyColumn(
|
fun ManagerLazyColumn(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
itemSpacing: Dp = 0.dp,
|
|
||||||
contentPadding: PaddingValues = PaddingValues(12.dp),
|
|
||||||
content: LazyListScope.() -> Unit
|
content: LazyListScope.() -> Unit
|
||||||
) {
|
) {
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
contentPadding = contentPadding,
|
|
||||||
verticalArrangement = Arrangement.spacedBy(itemSpacing),
|
|
||||||
content = content
|
content = content
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.vanced.manager.ui.component.layout
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
import androidx.compose.material3.*
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
|
||||||
|
@ExperimentalMaterial3Api
|
||||||
|
@Composable
|
||||||
|
fun ManagerScaffold(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
scaffoldState: ScaffoldState = rememberScaffoldState(),
|
||||||
|
topBar: @Composable () -> Unit = {},
|
||||||
|
floatingActionButton: @Composable () -> Unit = {},
|
||||||
|
floatingActionButtonPosition: FabPosition = FabPosition.End,
|
||||||
|
content: @Composable (PaddingValues) -> Unit
|
||||||
|
) {
|
||||||
|
// //M3 Scaffold doesn't support tonal elevation for Surface
|
||||||
|
// val absoluteTonalElevation = LocalAbsoluteTonalElevation.current + 1.dp
|
||||||
|
// CompositionLocalProvider(
|
||||||
|
// LocalAbsoluteTonalElevation provides absoluteTonalElevation
|
||||||
|
// ) {
|
||||||
|
Scaffold(
|
||||||
|
modifier = modifier,
|
||||||
|
scaffoldState = scaffoldState,
|
||||||
|
topBar = topBar,
|
||||||
|
floatingActionButton = floatingActionButton,
|
||||||
|
floatingActionButtonPosition = floatingActionButtonPosition,
|
||||||
|
content = content
|
||||||
|
)
|
||||||
|
// }
|
||||||
|
}
|
|
@ -4,7 +4,7 @@ import androidx.compose.animation.core.animateFloatAsState
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.foundation.Canvas
|
import androidx.compose.foundation.Canvas
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.SideEffect
|
import androidx.compose.runtime.SideEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
@ -20,7 +20,7 @@ fun ManagerScrim(
|
||||||
val systemUiController = rememberSystemUiController()
|
val systemUiController = rememberSystemUiController()
|
||||||
|
|
||||||
val scrimColor = Color.Black.copy(alpha = 0.5f)
|
val scrimColor = Color.Black.copy(alpha = 0.5f)
|
||||||
val surfaceColor = MaterialTheme.colors.surface
|
val surfaceColor = MaterialTheme.colorScheme.surface
|
||||||
|
|
||||||
val isDark = isDark()
|
val isDark = isDark()
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.vanced.manager.ui.component.layout
|
package com.vanced.manager.ui.component.layout
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.material.Surface
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import com.vanced.manager.ui.component.color.managerSurfaceColor
|
import com.vanced.manager.ui.component.color.managerSurfaceColor
|
||||||
|
|
|
@ -1,18 +1,25 @@
|
||||||
package com.vanced.manager.ui.component.layout
|
package com.vanced.manager.ui.component.layout
|
||||||
|
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
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
|
||||||
|
import com.vanced.manager.ui.component.card.ManagerCard
|
||||||
import com.vanced.manager.ui.component.color.managerAccentColor
|
import com.vanced.manager.ui.component.color.managerAccentColor
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ManagerSwipeRefresh(
|
fun ManagerSwipeRefresh(
|
||||||
refreshState: SwipeRefreshState,
|
refreshState: SwipeRefreshState,
|
||||||
onRefresh: () -> Unit,
|
onRefresh: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
content: @Composable () -> Unit
|
content: @Composable () -> Unit
|
||||||
) {
|
) {
|
||||||
SwipeRefresh(
|
SwipeRefresh(
|
||||||
|
modifier = modifier,
|
||||||
state = refreshState,
|
state = refreshState,
|
||||||
onRefresh = onRefresh,
|
onRefresh = onRefresh,
|
||||||
indicator = { state, trigger ->
|
indicator = { state, trigger ->
|
||||||
|
@ -20,7 +27,8 @@ fun ManagerSwipeRefresh(
|
||||||
state = state,
|
state = state,
|
||||||
refreshTriggerDistance = trigger,
|
refreshTriggerDistance = trigger,
|
||||||
scale = true,
|
scale = true,
|
||||||
contentColor = managerAccentColor()
|
contentColor = MaterialTheme.colorScheme.primary,
|
||||||
|
backgroundColor = MaterialTheme.colorScheme.surface
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
content = content
|
content = content
|
||||||
|
|
|
@ -12,11 +12,12 @@ import androidx.compose.ui.unit.dp
|
||||||
@Composable
|
@Composable
|
||||||
fun <T> ScrollableItemRow(
|
fun <T> ScrollableItemRow(
|
||||||
items: List<T>,
|
items: List<T>,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
content: @Composable (T) -> Unit
|
content: @Composable (T) -> Unit
|
||||||
) {
|
) {
|
||||||
val state = rememberLazyListState()
|
val state = rememberLazyListState()
|
||||||
LazyRow(
|
LazyRow(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = modifier,
|
||||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||||
state = state
|
state = state
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
package com.vanced.manager.ui.component.menu
|
||||||
|
|
||||||
|
import androidx.compose.animation.*
|
||||||
|
import androidx.compose.animation.core.*
|
||||||
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.ui.ExperimentalComposeUiApi
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.alpha
|
||||||
|
import androidx.compose.ui.draw.scale
|
||||||
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
|
import androidx.compose.ui.unit.*
|
||||||
|
import androidx.compose.ui.window.Popup
|
||||||
|
import androidx.compose.ui.window.PopupPositionProvider
|
||||||
|
import androidx.compose.ui.window.PopupProperties
|
||||||
|
import com.vanced.manager.ui.component.card.ManagerCard
|
||||||
|
|
||||||
|
private const val TransitionDuration = 200
|
||||||
|
|
||||||
|
@ExperimentalAnimationApi
|
||||||
|
@OptIn(ExperimentalComposeUiApi::class)
|
||||||
|
@Composable
|
||||||
|
fun ManagerDropdownMenu(
|
||||||
|
expanded: Boolean,
|
||||||
|
onDismissRequest: () -> Unit,
|
||||||
|
content: @Composable ColumnScope.() -> Unit,
|
||||||
|
) {
|
||||||
|
val expandedStates = remember { MutableTransitionState(false) }
|
||||||
|
expandedStates.targetState = expanded
|
||||||
|
|
||||||
|
val transition = updateTransition(expandedStates, "ManagerDropDownMenu")
|
||||||
|
|
||||||
|
val alphaAndScale by transition.animateFloat(
|
||||||
|
transitionSpec = { tween(durationMillis = TransitionDuration) },
|
||||||
|
label = "AlphaAndScale"
|
||||||
|
) {
|
||||||
|
if (it) 1f else 0f
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expandedStates.currentState || expandedStates.targetState) {
|
||||||
|
val density = LocalDensity.current
|
||||||
|
val popupPositionProvider =
|
||||||
|
ManagerDropdownMenuPopupPositionProvider(density)
|
||||||
|
|
||||||
|
Popup(
|
||||||
|
popupPositionProvider = popupPositionProvider,
|
||||||
|
onDismissRequest = onDismissRequest,
|
||||||
|
properties = PopupProperties(focusable = true)
|
||||||
|
) {
|
||||||
|
ManagerCard(
|
||||||
|
modifier = Modifier
|
||||||
|
.width(IntrinsicSize.Max)
|
||||||
|
.alpha(alphaAndScale)
|
||||||
|
.scale(alphaAndScale),
|
||||||
|
tonalElevation = 2.dp,
|
||||||
|
shadowElevation = 2.dp
|
||||||
|
) {
|
||||||
|
Column(content = content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Kanged from Menu.kt
|
||||||
|
data class ManagerDropdownMenuPopupPositionProvider(
|
||||||
|
val density: Density
|
||||||
|
) : PopupPositionProvider {
|
||||||
|
|
||||||
|
override fun calculatePosition(
|
||||||
|
anchorBounds: IntRect,
|
||||||
|
windowSize: IntSize,
|
||||||
|
layoutDirection: LayoutDirection,
|
||||||
|
popupContentSize: IntSize
|
||||||
|
): IntOffset {
|
||||||
|
val verticalMargin = with(density) { 48.dp.roundToPx() }
|
||||||
|
|
||||||
|
//Compute horizontal position.
|
||||||
|
val toRight = anchorBounds.left
|
||||||
|
val toLeft = anchorBounds.right - popupContentSize.width
|
||||||
|
val toDisplayRight = windowSize.width - popupContentSize.width
|
||||||
|
val toDisplayLeft = 0
|
||||||
|
val x = if (layoutDirection == LayoutDirection.Ltr) {
|
||||||
|
sequenceOf(toRight, toLeft, toDisplayRight)
|
||||||
|
} else {
|
||||||
|
sequenceOf(toLeft, toRight, toDisplayLeft)
|
||||||
|
}.firstOrNull {
|
||||||
|
it >= 0 && it + popupContentSize.width <= windowSize.width
|
||||||
|
} ?: toLeft
|
||||||
|
|
||||||
|
// Compute vertical position.
|
||||||
|
val toBottom = maxOf(anchorBounds.bottom, verticalMargin)
|
||||||
|
val toTop = anchorBounds.top - popupContentSize.height
|
||||||
|
val toCenter = anchorBounds.top - popupContentSize.height / 2
|
||||||
|
val toDisplayBottom = windowSize.height - popupContentSize.height - verticalMargin
|
||||||
|
val y = sequenceOf(toBottom, toTop, toCenter, toDisplayBottom).firstOrNull {
|
||||||
|
it >= verticalMargin &&
|
||||||
|
it + popupContentSize.height <= windowSize.height - verticalMargin
|
||||||
|
} ?: toTop
|
||||||
|
|
||||||
|
return IntOffset(x, y)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,9 +1,12 @@
|
||||||
package com.vanced.manager.ui.component.menu
|
package com.vanced.manager.ui.component.menu
|
||||||
|
|
||||||
import androidx.compose.material.DropdownMenuItem
|
import androidx.compose.material.DropdownMenuItem
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
import com.vanced.manager.ui.component.text.ManagerText
|
import com.vanced.manager.ui.component.text.ManagerText
|
||||||
|
import com.vanced.manager.ui.theme.SmallShape
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ManagerDropdownMenuItem(
|
fun ManagerDropdownMenuItem(
|
||||||
|
@ -12,10 +15,11 @@ fun ManagerDropdownMenuItem(
|
||||||
) {
|
) {
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
onClick = onClick,
|
onClick = onClick,
|
||||||
|
modifier = Modifier.clip(SmallShape),
|
||||||
) {
|
) {
|
||||||
ManagerText(
|
ManagerText(
|
||||||
text = title,
|
text = title,
|
||||||
textStyle = MaterialTheme.typography.h6
|
textStyle = MaterialTheme.typography.labelLarge
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,12 +2,12 @@ package com.vanced.manager.ui.component.modifier
|
||||||
|
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
import androidx.compose.material.MaterialTheme
|
|
||||||
import androidx.compose.material.ripple.rememberRipple
|
import androidx.compose.material.ripple.rememberRipple
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.composed
|
import androidx.compose.ui.composed
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
|
import com.vanced.manager.ui.theme.MediumShape
|
||||||
|
|
||||||
fun Modifier.managerClickable(
|
fun Modifier.managerClickable(
|
||||||
onClick: () -> Unit
|
onClick: () -> Unit
|
||||||
|
@ -15,9 +15,7 @@ fun Modifier.managerClickable(
|
||||||
val ripple = rememberRipple()
|
val ripple = rememberRipple()
|
||||||
val interactionSource = remember { MutableInteractionSource() }
|
val interactionSource = remember { MutableInteractionSource() }
|
||||||
|
|
||||||
return@composed then(
|
then(clip(MediumShape)).then(
|
||||||
clip(MaterialTheme.shapes.medium)
|
|
||||||
).then(
|
|
||||||
clickable(
|
clickable(
|
||||||
interactionSource = interactionSource,
|
interactionSource = interactionSource,
|
||||||
onClick = onClick,
|
onClick = onClick,
|
||||||
|
|
|
@ -4,6 +4,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.heightIn
|
import androidx.compose.foundation.layout.heightIn
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.material.TextButton
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
@ -15,6 +16,7 @@ import com.vanced.manager.R
|
||||||
import com.vanced.manager.core.preferences.CheckboxPreference
|
import com.vanced.manager.core.preferences.CheckboxPreference
|
||||||
import com.vanced.manager.core.preferences.ManagerPreference
|
import com.vanced.manager.core.preferences.ManagerPreference
|
||||||
import com.vanced.manager.ui.component.button.ManagerThemedTextButton
|
import com.vanced.manager.ui.component.button.ManagerThemedTextButton
|
||||||
|
import com.vanced.manager.ui.component.text.ManagerText
|
||||||
import com.vanced.manager.ui.widget.list.CheckboxItem
|
import com.vanced.manager.ui.widget.list.CheckboxItem
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
@ -37,10 +39,8 @@ fun CheckboxDialogPreference(
|
||||||
}
|
}
|
||||||
}.sortedBy { it.title }.joinToString(separator = ", ") { it.title },
|
}.sortedBy { it.title }.joinToString(separator = ", ") { it.title },
|
||||||
trailing = trailing,
|
trailing = trailing,
|
||||||
buttons = { isShown ->
|
confirmButton = { isShown ->
|
||||||
ManagerThemedTextButton(
|
TextButton(
|
||||||
text = stringResource(id = R.string.dialog_button_save),
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
onClick = {
|
onClick = {
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
isShown.value = false
|
isShown.value = false
|
||||||
|
@ -48,8 +48,10 @@ fun CheckboxDialogPreference(
|
||||||
onSave(selectedButtons)
|
onSave(selectedButtons)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
) {
|
||||||
}
|
ManagerText(stringResource(id = R.string.dialog_button_save))
|
||||||
|
}
|
||||||
|
},
|
||||||
) {
|
) {
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
modifier = Modifier.heightIn(max = 400.dp)
|
modifier = Modifier.heightIn(max = 400.dp)
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package com.vanced.manager.ui.component.preference
|
package com.vanced.manager.ui.component.preference
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.ColumnScope
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.MutableState
|
import androidx.compose.runtime.MutableState
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
@ -13,8 +12,9 @@ fun DialogPreference(
|
||||||
preferenceDescription: String? = null,
|
preferenceDescription: String? = null,
|
||||||
onDismissRequest: () -> Unit = {},
|
onDismissRequest: () -> Unit = {},
|
||||||
trailing: @Composable () -> Unit = {},
|
trailing: @Composable () -> Unit = {},
|
||||||
buttons: @Composable ColumnScope.(isShown: MutableState<Boolean>) -> Unit,
|
confirmButton: @Composable (isShown: MutableState<Boolean>) -> Unit,
|
||||||
content: @Composable ColumnScope.() -> Unit
|
dismissButton: @Composable ((isShown: MutableState<Boolean>) -> Unit)? = null,
|
||||||
|
content: @Composable () -> Unit
|
||||||
) {
|
) {
|
||||||
val isShown = remember { mutableStateOf(false) }
|
val isShown = remember { mutableStateOf(false) }
|
||||||
Preference(
|
Preference(
|
||||||
|
@ -31,7 +31,14 @@ fun DialogPreference(
|
||||||
onDismissRequest()
|
onDismissRequest()
|
||||||
isShown.value = false
|
isShown.value = false
|
||||||
},
|
},
|
||||||
buttons = { buttons(isShown) },
|
confirmButton = {
|
||||||
|
confirmButton(isShown)
|
||||||
|
},
|
||||||
|
dismissButton = {
|
||||||
|
if (dismissButton != null) {
|
||||||
|
dismissButton(isShown)
|
||||||
|
}
|
||||||
|
},
|
||||||
content = content
|
content = content
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package com.vanced.manager.ui.component.preference
|
package com.vanced.manager.ui.component.preference
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material.LocalContentColor
|
import androidx.compose.material3.LocalContentColor
|
||||||
import androidx.compose.material.LocalTextStyle
|
import androidx.compose.material3.LocalTextStyle
|
||||||
import androidx.compose.material.MaterialTheme
|
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.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
@ -39,7 +39,7 @@ fun Preference(
|
||||||
trailing: @Composable () -> Unit = {},
|
trailing: @Composable () -> Unit = {},
|
||||||
onClick: () -> Unit
|
onClick: () -> Unit
|
||||||
) {
|
) {
|
||||||
val color = managerAnimatedColor(color = MaterialTheme.colors.onSurface)
|
val color = managerAnimatedColor(color = MaterialTheme.colorScheme.onSurface)
|
||||||
ManagerListItem(
|
ManagerListItem(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.managerClickable(onClick = onClick)
|
.managerClickable(onClick = onClick)
|
||||||
|
@ -47,7 +47,7 @@ fun Preference(
|
||||||
title = {
|
title = {
|
||||||
CompositionLocalProvider(
|
CompositionLocalProvider(
|
||||||
LocalContentColor provides color,
|
LocalContentColor provides color,
|
||||||
LocalTextStyle provides MaterialTheme.typography.h6
|
LocalTextStyle provides MaterialTheme.typography.titleSmall
|
||||||
) {
|
) {
|
||||||
preferenceTitle()
|
preferenceTitle()
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ fun Preference(
|
||||||
{
|
{
|
||||||
CompositionLocalProvider(
|
CompositionLocalProvider(
|
||||||
LocalContentColor provides color,
|
LocalContentColor provides color,
|
||||||
LocalTextStyle provides MaterialTheme.typography.subtitle1
|
LocalTextStyle provides MaterialTheme.typography.bodySmall
|
||||||
) {
|
) {
|
||||||
preferenceDescription()
|
preferenceDescription()
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,15 @@ package com.vanced.manager.ui.component.preference
|
||||||
import androidx.compose.foundation.layout.heightIn
|
import androidx.compose.foundation.layout.heightIn
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.material3.TextButton
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
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.R
|
||||||
import com.vanced.manager.core.preferences.ManagerPreference
|
import com.vanced.manager.core.preferences.ManagerPreference
|
||||||
import com.vanced.manager.core.preferences.RadioButtonPreference
|
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.button.ManagerSaveButton
|
import com.vanced.manager.ui.widget.button.ManagerSaveButton
|
||||||
import com.vanced.manager.ui.widget.list.RadiobuttonItem
|
import com.vanced.manager.ui.widget.list.RadiobuttonItem
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
@ -27,13 +31,13 @@ fun RadiobuttonDialogPreference(
|
||||||
preferenceTitle = preferenceTitle,
|
preferenceTitle = preferenceTitle,
|
||||||
preferenceDescription = buttons.find { it.key == pref }?.title,
|
preferenceDescription = buttons.find { it.key == pref }?.title,
|
||||||
trailing = trailing,
|
trailing = trailing,
|
||||||
buttons = { isShown ->
|
confirmButton = { isShown ->
|
||||||
ManagerSaveButton {
|
TextButton(onClick = {
|
||||||
coroutineScope.launch {
|
isShown.value = false
|
||||||
isShown.value = false
|
pref = currentSelection
|
||||||
pref = currentSelection
|
onSave(currentSelection)
|
||||||
onSave(currentSelection)
|
}) {
|
||||||
}
|
ManagerText(managerString(stringId = R.string.dialog_button_save))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -4,7 +4,6 @@ import androidx.compose.animation.core.animateFloatAsState
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.material.LinearProgressIndicator
|
import androidx.compose.material.LinearProgressIndicator
|
||||||
import androidx.compose.material.MaterialTheme
|
|
||||||
import androidx.compose.material.ProgressIndicatorDefaults
|
import androidx.compose.material.ProgressIndicatorDefaults
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
@ -13,11 +12,12 @@ import androidx.compose.ui.composed
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.vanced.manager.ui.component.color.managerAccentColor
|
import com.vanced.manager.ui.component.color.managerAccentColor
|
||||||
|
import com.vanced.manager.ui.theme.MediumShape
|
||||||
|
|
||||||
private val progressBarModifier = Modifier.composed {
|
private val progressBarModifier = Modifier.composed {
|
||||||
then(height(5.dp))
|
then(height(5.dp))
|
||||||
.then(fillMaxWidth())
|
.then(fillMaxWidth())
|
||||||
.then(clip(MaterialTheme.shapes.medium))
|
.then(clip(MediumShape))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|
|
@ -1,25 +1,24 @@
|
||||||
package com.vanced.manager.ui.component.radiobutton
|
package com.vanced.manager.ui.component.radiobutton
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Shape
|
import androidx.compose.ui.graphics.Shape
|
||||||
import com.vanced.manager.ui.component.card.ManagerCard
|
import com.vanced.manager.ui.component.card.ManagerCard
|
||||||
import com.vanced.manager.ui.component.color.managerAccentColor
|
|
||||||
import com.vanced.manager.ui.component.color.managerAnimatedColor
|
import com.vanced.manager.ui.component.color.managerAnimatedColor
|
||||||
import com.vanced.manager.ui.component.color.managerThemedCardColor
|
import com.vanced.manager.ui.theme.MediumShape
|
||||||
|
|
||||||
@SuppressLint("UnusedTransitionTargetStateParameter")
|
@SuppressLint("UnusedTransitionTargetStateParameter")
|
||||||
@Composable
|
@Composable
|
||||||
fun ManagerRadiobutton(
|
fun ManagerRadiobutton(
|
||||||
modifier: Modifier,
|
modifier: Modifier,
|
||||||
isSelected: Boolean,
|
isSelected: Boolean,
|
||||||
shape: Shape = MaterialTheme.shapes.medium,
|
shape: Shape = MediumShape,
|
||||||
onClick: () -> Unit
|
onClick: () -> Unit
|
||||||
) {
|
) {
|
||||||
val accentColor = managerAccentColor()
|
val cardColor =
|
||||||
val cardColor = managerAnimatedColor(if (isSelected) accentColor else managerThemedCardColor())
|
managerAnimatedColor(if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.primaryContainer)
|
||||||
ManagerCard(
|
ManagerCard(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
onClick = onClick,
|
onClick = onClick,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.vanced.manager.ui.component.text
|
package com.vanced.manager.ui.component.text
|
||||||
|
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
|
||||||
|
@ -12,6 +12,6 @@ fun AppVersionText(
|
||||||
ManagerText(
|
ManagerText(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
text = text,
|
text = text,
|
||||||
textStyle = MaterialTheme.typography.body2,
|
textStyle = MaterialTheme.typography.bodySmall,
|
||||||
)
|
)
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
package com.vanced.manager.ui.component.text
|
package com.vanced.manager.ui.component.text
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import com.vanced.manager.ui.component.color.managerAnimatedColor
|
import com.vanced.manager.ui.component.color.managerAnimatedColor
|
||||||
|
@ -14,7 +14,7 @@ fun CategoryTitleText(
|
||||||
ManagerText(
|
ManagerText(
|
||||||
modifier = Modifier.padding(start = DefaultContentPaddingHorizontal),
|
modifier = Modifier.padding(start = DefaultContentPaddingHorizontal),
|
||||||
text = text,
|
text = text,
|
||||||
textStyle = MaterialTheme.typography.h2,
|
textStyle = MaterialTheme.typography.headlineSmall,
|
||||||
color = managerAnimatedColor(MaterialTheme.colors.onSurface)
|
color = managerAnimatedColor(MaterialTheme.colorScheme.onSurface)
|
||||||
)
|
)
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
package com.vanced.manager.ui.component.text
|
package com.vanced.manager.ui.component.text
|
||||||
|
|
||||||
import androidx.compose.material.LocalTextStyle
|
import androidx.compose.material3.LocalTextStyle
|
||||||
import androidx.compose.material.Text
|
import androidx.compose.material3.Text
|
||||||
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 androidx.compose.ui.graphics.Color
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.vanced.manager.ui.component.text
|
package com.vanced.manager.ui.component.text
|
||||||
|
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import com.vanced.manager.ui.component.color.managerAnimatedColor
|
import com.vanced.manager.ui.component.color.managerAnimatedColor
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ fun ToolbarTitleText(
|
||||||
) {
|
) {
|
||||||
ManagerText(
|
ManagerText(
|
||||||
text = text,
|
text = text,
|
||||||
textStyle = MaterialTheme.typography.h1,
|
textStyle = MaterialTheme.typography.headlineMedium,
|
||||||
color = managerAnimatedColor(MaterialTheme.colors.onSurface)
|
color = managerAnimatedColor(MaterialTheme.colorScheme.onSurface)
|
||||||
)
|
)
|
||||||
}
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
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,
|
||||||
|
)
|
||||||
|
}
|
|
@ -2,11 +2,13 @@ package com.vanced.manager.ui.screens
|
||||||
|
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.material.icons.rounded.ArrowBackIosNew
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
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
|
||||||
|
@ -15,96 +17,83 @@ import androidx.compose.ui.text.SpanStyle
|
||||||
import androidx.compose.ui.text.buildAnnotatedString
|
import androidx.compose.ui.text.buildAnnotatedString
|
||||||
import androidx.compose.ui.text.withStyle
|
import androidx.compose.ui.text.withStyle
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.util.fastForEach
|
|
||||||
import com.vanced.manager.R
|
import com.vanced.manager.R
|
||||||
import com.vanced.manager.ui.component.card.ManagerLinkCard
|
import com.vanced.manager.ui.component.card.ManagerLinkCard
|
||||||
import com.vanced.manager.ui.component.card.ManagerThemedCard
|
import com.vanced.manager.ui.component.card.ManagerTonalCard
|
||||||
import com.vanced.manager.ui.component.layout.ManagerScrollableColumn
|
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.layout.ScrollableItemRow
|
||||||
import com.vanced.manager.ui.component.list.ManagerListItem
|
import com.vanced.manager.ui.component.list.ManagerListItem
|
||||||
import com.vanced.manager.ui.component.text.ManagerText
|
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.resources.managerString
|
||||||
|
import com.vanced.manager.ui.theme.LargeShape
|
||||||
|
import com.vanced.manager.ui.util.DefaultContentPaddingHorizontal
|
||||||
import com.vanced.manager.ui.util.DefaultContentPaddingVertical
|
import com.vanced.manager.ui.util.DefaultContentPaddingVertical
|
||||||
import com.vanced.manager.ui.widget.layout.CategoryLayout
|
import com.vanced.manager.ui.util.Screen
|
||||||
|
import com.vanced.manager.ui.widget.layout.managerCategory
|
||||||
|
|
||||||
data class Person(
|
data class Person(
|
||||||
val name: String,
|
val name: String,
|
||||||
val contribution: String
|
val contribution: String
|
||||||
)
|
)
|
||||||
|
|
||||||
data class Credit(
|
|
||||||
@StringRes val nameId: Int,
|
|
||||||
val persons: List<Person>
|
|
||||||
)
|
|
||||||
|
|
||||||
data class Source(
|
data class Source(
|
||||||
@StringRes val nameId: Int,
|
@StringRes val nameId: Int,
|
||||||
@DrawableRes val iconId: Int,
|
@DrawableRes val iconId: Int,
|
||||||
val link: String
|
val link: String
|
||||||
)
|
)
|
||||||
|
|
||||||
private val credits = listOf(
|
private val vancedTeam = listOf(
|
||||||
Credit(
|
Person(
|
||||||
nameId = R.string.about_category_credits_vanced_team,
|
name = "xfileFIN",
|
||||||
persons = listOf(
|
contribution = "Mods, Theming, Support"
|
||||||
Person(
|
|
||||||
name = "xfileFIN",
|
|
||||||
contribution = "Mods, Theming, Support"
|
|
||||||
),
|
|
||||||
Person(
|
|
||||||
name = "Laura",
|
|
||||||
contribution = "Theming, Support"
|
|
||||||
),
|
|
||||||
Person(
|
|
||||||
name = "ZaneZam",
|
|
||||||
contribution = "Publishing, Support"
|
|
||||||
),
|
|
||||||
Person(
|
|
||||||
name = "KevinX8",
|
|
||||||
contribution = "Overlord, Support"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
Credit(
|
Person(
|
||||||
nameId = R.string.about_category_credits_manager_devs,
|
name = "Laura",
|
||||||
persons = listOf(
|
contribution = "Theming, Support"
|
||||||
Person(
|
|
||||||
name = "Xinto",
|
|
||||||
contribution = "Manager Core"
|
|
||||||
),
|
|
||||||
Person(
|
|
||||||
name = "Koopah",
|
|
||||||
contribution = "Root installer"
|
|
||||||
),
|
|
||||||
Person(
|
|
||||||
name = "Logan",
|
|
||||||
contribution = "UI"
|
|
||||||
),
|
|
||||||
Person(
|
|
||||||
name = "HaliksaR",
|
|
||||||
contribution = "Refactoring, UI"
|
|
||||||
),
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
Credit(
|
Person(
|
||||||
nameId = R.string.about_category_credits_other,
|
name = "ZaneZam",
|
||||||
persons = listOf(
|
contribution = "Publishing, Support"
|
||||||
Person(
|
),
|
||||||
name = "bhatVikrant",
|
Person(
|
||||||
contribution = "Website"
|
name = "KevinX8",
|
||||||
),
|
contribution = "Overlord, Support"
|
||||||
Person(
|
),
|
||||||
name = "bawm",
|
Person(
|
||||||
contribution = "Sponsorblock"
|
name = "Xinto",
|
||||||
),
|
contribution = "Vanced Manager"
|
||||||
Person(
|
|
||||||
name = "cane",
|
|
||||||
contribution = "Sponsorblock"
|
|
||||||
),
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private val otherContributors = listOf(
|
||||||
|
Person(
|
||||||
|
name = "bhatVikrant",
|
||||||
|
contribution = "Website"
|
||||||
|
),
|
||||||
|
Person(
|
||||||
|
name = "bawm",
|
||||||
|
contribution = "Sponsorblock"
|
||||||
|
),
|
||||||
|
Person(
|
||||||
|
name = "cane",
|
||||||
|
contribution = "Sponsorblock"
|
||||||
|
),
|
||||||
|
Person(
|
||||||
|
name = "Koopah",
|
||||||
|
contribution = "Vanced Manager root installer"
|
||||||
|
),
|
||||||
|
Person(
|
||||||
|
name = "Logan",
|
||||||
|
contribution = "Vanced Manager UI"
|
||||||
|
),
|
||||||
|
Person(
|
||||||
|
name = "HaliksaR",
|
||||||
|
contribution = "Vanced Manager Refactoring, UI"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
private val sources = listOf(
|
private val sources = listOf(
|
||||||
Source(
|
Source(
|
||||||
nameId = R.string.about_sources_source_code,
|
nameId = R.string.about_sources_source_code,
|
||||||
|
@ -118,79 +107,119 @@ private val sources = listOf(
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ExperimentalMaterial3Api
|
||||||
@Composable
|
@Composable
|
||||||
fun AboutLayout() {
|
fun AboutLayout(
|
||||||
ManagerScrollableColumn(
|
onToolbarBackButtonClick: () -> Unit
|
||||||
itemSpacing = 12.dp
|
) {
|
||||||
) {
|
val aboutCategoryVancedTeam = managerString(R.string.about_category_credits_vanced_team)
|
||||||
AboutManagerCard()
|
val aboutCategoryOtherContributors = managerString(R.string.about_category_credits_other)
|
||||||
credits.fastForEach { credit ->
|
val aboutCategorySources = managerString(R.string.about_category_sources)
|
||||||
CategoryLayout(
|
|
||||||
categoryName = managerString(stringId = credit.nameId),
|
ManagerScaffold(
|
||||||
categoryNameSpacing = 4.dp
|
topBar = {
|
||||||
) {
|
ManagerTopAppBar(
|
||||||
Column {
|
title = managerString(Screen.About.displayName),
|
||||||
credit.persons.fastForEach { person ->
|
navigationIcon = {
|
||||||
ManagerListItem(
|
IconButton(onClick = onToolbarBackButtonClick) {
|
||||||
title = {
|
Icon(
|
||||||
ManagerText(
|
imageVector = Icons.Rounded.ArrowBackIosNew,
|
||||||
text = person.name,
|
contentDescription = "Back"
|
||||||
textStyle = MaterialTheme.typography.h6
|
)
|
||||||
)
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { paddingValues ->
|
||||||
|
ManagerLazyColumn(
|
||||||
|
modifier = Modifier.fillMaxSize().padding(paddingValues),
|
||||||
|
) {
|
||||||
|
item {
|
||||||
|
ManagerTonalCard(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
shape = LargeShape
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.padding(vertical = DefaultContentPaddingVertical),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
verticalArrangement = Arrangement.spacedBy(4.dp)
|
||||||
|
) {
|
||||||
|
ManagerText(
|
||||||
|
modifier = Modifier,
|
||||||
|
text = managerString(R.string.app_name),
|
||||||
|
textStyle = MaterialTheme.typography.headlineSmall
|
||||||
|
)
|
||||||
|
ManagerText(
|
||||||
|
modifier = Modifier,
|
||||||
|
text = buildAnnotatedString {
|
||||||
|
append("Re")
|
||||||
|
withStyle(style = SpanStyle(Color(0xFFBBB529))) {
|
||||||
|
append("@Compose")
|
||||||
|
}
|
||||||
|
append("d")
|
||||||
},
|
},
|
||||||
description = {
|
textStyle = MaterialTheme.typography.titleSmall
|
||||||
ManagerText(
|
|
||||||
text = person.contribution,
|
|
||||||
textStyle = MaterialTheme.typography.subtitle1
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
managerCategory(
|
||||||
CategoryLayout(
|
categoryName = aboutCategoryVancedTeam,
|
||||||
categoryName = managerString(
|
items = vancedTeam
|
||||||
stringId = R.string.about_category_sources
|
) { person ->
|
||||||
),
|
CreditPersonItem(
|
||||||
) {
|
modifier = Modifier.fillMaxWidth(),
|
||||||
ScrollableItemRow(items = sources) { source ->
|
personName = person.name,
|
||||||
ManagerLinkCard(
|
personContribution = person.contribution
|
||||||
title = managerString(source.nameId),
|
|
||||||
icon = source.iconId,
|
|
||||||
link = source.link
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
managerCategory(
|
||||||
|
categoryName = aboutCategoryOtherContributors,
|
||||||
|
items = otherContributors
|
||||||
|
) { person ->
|
||||||
|
CreditPersonItem(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
personName = person.name,
|
||||||
|
personContribution = person.contribution
|
||||||
|
)
|
||||||
|
}
|
||||||
|
managerCategory(aboutCategorySources) {
|
||||||
|
ScrollableItemRow(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(horizontal = DefaultContentPaddingHorizontal),
|
||||||
|
items = sources
|
||||||
|
) { source ->
|
||||||
|
ManagerLinkCard(
|
||||||
|
title = managerString(source.nameId),
|
||||||
|
icon = source.iconId,
|
||||||
|
link = source.link
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun AboutManagerCard() {
|
private fun CreditPersonItem(
|
||||||
ManagerThemedCard(
|
personName: String,
|
||||||
modifier = Modifier.fillMaxWidth()
|
personContribution: String,
|
||||||
) {
|
modifier: Modifier = Modifier,
|
||||||
Column(
|
) {
|
||||||
modifier = Modifier.padding(vertical = DefaultContentPaddingVertical),
|
ManagerListItem(
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
modifier = modifier.padding(horizontal = DefaultContentPaddingHorizontal),
|
||||||
verticalArrangement = Arrangement.spacedBy(4.dp)
|
title = {
|
||||||
) {
|
|
||||||
ManagerText(
|
ManagerText(
|
||||||
modifier = Modifier,
|
text = personName,
|
||||||
text = managerString(R.string.app_name),
|
textStyle = MaterialTheme.typography.titleSmall
|
||||||
textStyle = MaterialTheme.typography.h1
|
|
||||||
)
|
)
|
||||||
|
},
|
||||||
|
description = {
|
||||||
ManagerText(
|
ManagerText(
|
||||||
modifier = Modifier,
|
text = personContribution,
|
||||||
text = buildAnnotatedString {
|
textStyle = MaterialTheme.typography.bodySmall
|
||||||
append("Re")
|
|
||||||
withStyle(style = SpanStyle(Color(0xFFBBB529))) {
|
|
||||||
append("@Compose")
|
|
||||||
}
|
|
||||||
append("d")
|
|
||||||
},
|
|
||||||
textStyle = MaterialTheme.typography.h5
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
}
|
}
|
|
@ -1,15 +1,14 @@
|
||||||
package com.vanced.manager.ui.screens
|
package com.vanced.manager.ui.screens
|
||||||
|
|
||||||
import androidx.compose.animation.*
|
import androidx.compose.animation.*
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.material.icons.rounded.MoreVert
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.navigation.NavController
|
|
||||||
import coil.compose.rememberImagePainter
|
import coil.compose.rememberImagePainter
|
||||||
import coil.request.CachePolicy
|
import coil.request.CachePolicy
|
||||||
import com.google.accompanist.swiperefresh.rememberSwipeRefreshState
|
import com.google.accompanist.swiperefresh.rememberSwipeRefreshState
|
||||||
|
@ -19,23 +18,28 @@ import com.vanced.manager.core.util.sponsors
|
||||||
import com.vanced.manager.domain.model.InstallationOption
|
import com.vanced.manager.domain.model.InstallationOption
|
||||||
import com.vanced.manager.ui.component.card.ManagerLinkCard
|
import com.vanced.manager.ui.component.card.ManagerLinkCard
|
||||||
import com.vanced.manager.ui.component.dialog.ManagerDialog
|
import com.vanced.manager.ui.component.dialog.ManagerDialog
|
||||||
import com.vanced.manager.ui.component.layout.ManagerScrollableColumn
|
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.ManagerSwipeRefresh
|
||||||
import com.vanced.manager.ui.component.layout.ScrollableItemRow
|
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.text.ManagerText
|
||||||
|
import com.vanced.manager.ui.component.topappbar.ManagerTopAppBar
|
||||||
import com.vanced.manager.ui.resources.managerString
|
import com.vanced.manager.ui.resources.managerString
|
||||||
import com.vanced.manager.ui.util.DefaultContentPaddingVertical
|
import com.vanced.manager.ui.util.DefaultContentPaddingHorizontal
|
||||||
import com.vanced.manager.ui.util.Screen
|
import com.vanced.manager.ui.util.Screen
|
||||||
import com.vanced.manager.ui.viewmodel.MainViewModel
|
import com.vanced.manager.ui.viewmodel.MainViewModel
|
||||||
import com.vanced.manager.ui.widget.app.AppCard
|
import com.vanced.manager.ui.widget.app.AppCard
|
||||||
import com.vanced.manager.ui.widget.app.AppCardPlaceholder
|
import com.vanced.manager.ui.widget.app.AppCardPlaceholder
|
||||||
import com.vanced.manager.ui.widget.button.ManagerCloseButton
|
import com.vanced.manager.ui.widget.layout.managerCategory
|
||||||
import com.vanced.manager.ui.widget.layout.CategoryLayout
|
|
||||||
import org.koin.androidx.compose.getViewModel
|
import org.koin.androidx.compose.getViewModel
|
||||||
|
|
||||||
|
@ExperimentalMaterial3Api
|
||||||
@ExperimentalAnimationApi
|
@ExperimentalAnimationApi
|
||||||
@Composable
|
@Composable
|
||||||
fun HomeLayout(
|
fun HomeLayout(
|
||||||
|
onToolbarScreenSelected: (Screen) -> Unit,
|
||||||
onAppInstallPress: (
|
onAppInstallPress: (
|
||||||
appName: String,
|
appName: String,
|
||||||
appVersions: List<String>?,
|
appVersions: List<String>?,
|
||||||
|
@ -43,102 +47,152 @@ fun HomeLayout(
|
||||||
) -> Unit
|
) -> Unit
|
||||||
) {
|
) {
|
||||||
val viewModel: MainViewModel = getViewModel()
|
val viewModel: MainViewModel = getViewModel()
|
||||||
|
|
||||||
val appState by viewModel.appState.collectAsState()
|
val appState by viewModel.appState.collectAsState()
|
||||||
|
|
||||||
val refreshState = rememberSwipeRefreshState(isRefreshing = appState is MainViewModel.AppState.Fetching)
|
val refreshState = rememberSwipeRefreshState(isRefreshing = appState is MainViewModel.AppState.Fetching)
|
||||||
ManagerSwipeRefresh(
|
var isMenuExpanded by remember { mutableStateOf(false) }
|
||||||
refreshState = refreshState,
|
val dropdownScreens = remember { listOf(Screen.Settings, Screen.About) }
|
||||||
onRefresh = { viewModel.fetch() }
|
|
||||||
) {
|
val homeCategoryApps = managerString(R.string.home_category_apps)
|
||||||
ManagerScrollableColumn(
|
val homeCategorySupportUs = managerString(R.string.home_category_support_us)
|
||||||
contentPaddingVertical = DefaultContentPaddingVertical,
|
val homeCategorySocialMedia = managerString(R.string.home_category_social_media)
|
||||||
itemSpacing = 18.dp
|
|
||||||
) {
|
ManagerScaffold(
|
||||||
CategoryLayout(
|
topBar = {
|
||||||
categoryName = managerString(R.string.home_category_apps),
|
ManagerTopAppBar(
|
||||||
contentPaddingHorizontal = 0.dp
|
title = managerString(Screen.Home.displayName),
|
||||||
) {
|
actions = {
|
||||||
AnimatedContent(
|
IconButton(onClick = { isMenuExpanded = true }) {
|
||||||
targetState = appState,
|
Icon(
|
||||||
transitionSpec = {
|
Icons.Rounded.MoreVert,
|
||||||
scaleIn(initialScale = 0.9f) + fadeIn() with
|
contentDescription = "Navigation"
|
||||||
scaleOut(targetScale = 0.9f) + fadeOut()
|
)
|
||||||
}
|
}
|
||||||
) { animatedAppState ->
|
|
||||||
Column(
|
ManagerDropdownMenu(
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
expanded = isMenuExpanded,
|
||||||
|
onDismissRequest = {
|
||||||
|
isMenuExpanded = false
|
||||||
|
}
|
||||||
) {
|
) {
|
||||||
when (animatedAppState) {
|
for (dropdownScreen in dropdownScreens) {
|
||||||
is MainViewModel.AppState.Success -> {
|
ManagerDropdownMenuItem(
|
||||||
for (app in animatedAppState.apps) {
|
title = managerString(dropdownScreen.displayName),
|
||||||
val appIcon = rememberImagePainter(app.iconUrl) {
|
onClick = {
|
||||||
diskCachePolicy(CachePolicy.ENABLED)
|
onToolbarScreenSelected(dropdownScreen)
|
||||||
}
|
isMenuExpanded = false
|
||||||
|
}
|
||||||
var showAppInfoDialog by rememberSaveable { mutableStateOf(false) }
|
)
|
||||||
|
}
|
||||||
AppCard(
|
}
|
||||||
appName = app.name,
|
}
|
||||||
appIcon = appIcon,
|
)
|
||||||
appInstalledVersion = app.installedVersion,
|
}
|
||||||
appRemoteVersion = app.remoteVersion,
|
) { paddingValues ->
|
||||||
onDownloadClick = {
|
ManagerSwipeRefresh(
|
||||||
onAppInstallPress(app.name, app.versions, app.installationOptions)
|
modifier = Modifier
|
||||||
},
|
.fillMaxSize()
|
||||||
onUninstallClick = { /*TODO*/ },
|
.padding(paddingValues),
|
||||||
onLaunchClick = { /*TODO*/ },
|
refreshState = refreshState,
|
||||||
onInfoClick = {
|
onRefresh = { viewModel.fetch() }
|
||||||
showAppInfoDialog = true
|
) {
|
||||||
|
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)
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
if (showAppInfoDialog) {
|
var showAppInfoDialog by rememberSaveable { mutableStateOf(false) }
|
||||||
ManagerDialog(
|
|
||||||
title = managerString(R.string.app_info_title, app.name),
|
AppCard(
|
||||||
onDismissRequest = { showAppInfoDialog = false },
|
appName = app.name,
|
||||||
buttons = {
|
appIcon = appIcon,
|
||||||
ManagerCloseButton(onClick = {
|
appInstalledVersion = app.installedVersion,
|
||||||
showAppInfoDialog = false
|
appRemoteVersion = app.remoteVersion,
|
||||||
})
|
onAppDownloadClick = {
|
||||||
|
onAppInstallPress(app.name, app.versions, app.installationOptions)
|
||||||
|
},
|
||||||
|
onAppUninstallClick = { /*TODO*/ },
|
||||||
|
onAppLaunchClick = { /*TODO*/ },
|
||||||
|
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
|
||||||
|
)
|
||||||
}
|
}
|
||||||
) {
|
|
||||||
ManagerText(
|
|
||||||
modifier = Modifier.padding(top = 4.dp),
|
|
||||||
text = app.changelog,
|
|
||||||
textStyle = MaterialTheme.typography.subtitle1
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
is MainViewModel.AppState.Fetching -> {
|
||||||
is MainViewModel.AppState.Fetching -> {
|
for (i in 0 until animatedAppState.placeholderAppsCount) {
|
||||||
for (i in 0 until animatedAppState.placeholderAppsCount) {
|
AppCardPlaceholder()
|
||||||
AppCardPlaceholder()
|
}
|
||||||
}
|
}
|
||||||
}
|
is MainViewModel.AppState.Error -> {
|
||||||
is MainViewModel.AppState.Error -> {
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
managerCategory(homeCategorySupportUs) {
|
||||||
CategoryLayout(managerString(R.string.home_category_support_us)) {
|
ScrollableItemRow(
|
||||||
ScrollableItemRow(items = sponsors) { sponsor ->
|
modifier = Modifier
|
||||||
ManagerLinkCard(
|
.fillMaxWidth()
|
||||||
icon = sponsor.icon,
|
.padding(horizontal = DefaultContentPaddingHorizontal),
|
||||||
title = sponsor.title,
|
items = sponsors
|
||||||
link = sponsor.link
|
) { sponsor ->
|
||||||
)
|
ManagerLinkCard(
|
||||||
|
icon = sponsor.icon,
|
||||||
|
title = sponsor.title,
|
||||||
|
link = sponsor.link
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
managerCategory(homeCategorySocialMedia) {
|
||||||
CategoryLayout( managerString(R.string.home_category_social_media)) {
|
ScrollableItemRow(
|
||||||
ScrollableItemRow(items = socialMedia) { socialMedia ->
|
modifier = Modifier
|
||||||
ManagerLinkCard(
|
.fillMaxWidth()
|
||||||
icon = socialMedia.icon,
|
.padding(horizontal = DefaultContentPaddingHorizontal),
|
||||||
title = socialMedia.title,
|
items = socialMedia
|
||||||
link = socialMedia.link
|
) { socialMedia ->
|
||||||
)
|
ManagerLinkCard(
|
||||||
|
icon = socialMedia.icon,
|
||||||
|
title = socialMedia.title,
|
||||||
|
link = socialMedia.link
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,121 +1,144 @@
|
||||||
package com.vanced.manager.ui.screens
|
package com.vanced.manager.ui.screens
|
||||||
|
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.*
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.layout.sizeIn
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.material.FloatingActionButton
|
|
||||||
import androidx.compose.material.Icon
|
|
||||||
import androidx.compose.material.Scaffold
|
|
||||||
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.Done
|
import androidx.compose.material.icons.rounded.Done
|
||||||
|
import androidx.compose.material.icons.rounded.NavigateBefore
|
||||||
|
import androidx.compose.material.icons.rounded.NavigateNext
|
||||||
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.text.TextStyle
|
import com.vanced.manager.R
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.compose.ui.unit.sp
|
|
||||||
import androidx.compose.ui.util.fastForEach
|
|
||||||
import androidx.compose.ui.util.fastForEachIndexed
|
|
||||||
import com.vanced.manager.domain.model.InstallationOption
|
import com.vanced.manager.domain.model.InstallationOption
|
||||||
import com.vanced.manager.ui.component.card.ManagerClickableThemedCard
|
import com.vanced.manager.ui.component.card.ManagerTonalCard
|
||||||
import com.vanced.manager.ui.component.layout.ManagerScrollableColumn
|
import com.vanced.manager.ui.component.layout.ManagerLazyColumn
|
||||||
|
import com.vanced.manager.ui.component.layout.ManagerScaffold
|
||||||
|
import com.vanced.manager.ui.component.progressindicator.ManagerProgressIndicator
|
||||||
import com.vanced.manager.ui.component.text.ManagerText
|
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.resources.managerString
|
||||||
|
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.widget.list.CheckboxItem
|
import com.vanced.manager.ui.widget.list.CheckboxItem
|
||||||
import com.vanced.manager.ui.widget.list.RadiobuttonItem
|
import com.vanced.manager.ui.widget.list.RadiobuttonItem
|
||||||
|
|
||||||
|
@ExperimentalFoundationApi
|
||||||
|
@ExperimentalAnimationApi
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun InstallPreferencesScreen(
|
fun InstallPreferencesScreen(
|
||||||
installationOptions: List<InstallationOption>,
|
installationOptions: List<InstallationOption>,
|
||||||
onDoneClick: () -> Unit
|
onToolbarBackButtonClick: () -> Unit,
|
||||||
|
onDoneClick: () -> Unit,
|
||||||
) {
|
) {
|
||||||
var selectedOptionIndex by rememberSaveable { mutableStateOf(0) }
|
var currentOptionIndex by rememberSaveable { mutableStateOf(0) }
|
||||||
|
|
||||||
Scaffold(
|
ManagerScaffold(
|
||||||
floatingActionButton = {
|
topBar = {
|
||||||
FloatingActionButton(
|
Column {
|
||||||
onClick = onDoneClick
|
ManagerTopAppBar(
|
||||||
) {
|
title = managerString(R.string.toolbar_installation_preferences),
|
||||||
Icon(
|
navigationIcon = {
|
||||||
imageVector = Icons.Rounded.Done,
|
IconButton(
|
||||||
contentDescription = "Done"
|
onClick = onToolbarBackButtonClick
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Rounded.ArrowBackIosNew,
|
||||||
|
contentDescription = "Back"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
ManagerProgressIndicator(
|
||||||
|
progress = (currentOptionIndex + 1).toFloat() / installationOptions.size.toFloat()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
ManagerScrollableColumn(
|
Column(
|
||||||
modifier = Modifier.padding(paddingValues),
|
modifier = Modifier
|
||||||
itemSpacing = DefaultContentPaddingVertical
|
.fillMaxSize()
|
||||||
|
.padding(paddingValues),
|
||||||
) {
|
) {
|
||||||
installationOptions.fastForEachIndexed { index, installationOption ->
|
AnimatedContent(
|
||||||
ManagerClickableThemedCard(
|
modifier = Modifier
|
||||||
|
.padding(
|
||||||
|
horizontal = DefaultContentPaddingHorizontal,
|
||||||
|
vertical = DefaultContentPaddingVertical
|
||||||
|
)
|
||||||
|
.weight(1f),
|
||||||
|
targetState = currentOptionIndex,
|
||||||
|
transitionSpec = {
|
||||||
|
getSlideAnimationSpec(
|
||||||
|
if (targetState > initialState) {
|
||||||
|
AnimatedContentScope.SlideDirection.Start
|
||||||
|
} else {
|
||||||
|
AnimatedContentScope.SlideDirection.End
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { optionIndex ->
|
||||||
|
val installationOption = installationOptions[optionIndex]
|
||||||
|
ManagerTonalCard(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.wrapContentHeight(
|
||||||
.padding(horizontal = DefaultContentPaddingHorizontal),
|
align = Alignment.Top
|
||||||
onClick = {
|
),
|
||||||
selectedOptionIndex = index
|
shape = LargeShape
|
||||||
}
|
|
||||||
) {
|
) {
|
||||||
Column(
|
Column {
|
||||||
modifier = Modifier.padding(12.dp)
|
|
||||||
) {
|
|
||||||
ManagerText(
|
ManagerText(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(
|
||||||
|
horizontal = DefaultContentPaddingHorizontal,
|
||||||
|
vertical = DefaultContentPaddingVertical
|
||||||
|
),
|
||||||
text = managerString(installationOption.itemTitleId),
|
text = managerString(installationOption.itemTitleId),
|
||||||
textStyle = TextStyle(
|
textStyle = MaterialTheme.typography.titleLarge,
|
||||||
fontSize = 20.sp,
|
|
||||||
fontWeight = FontWeight.SemiBold
|
|
||||||
),
|
|
||||||
textAlign = TextAlign.Center
|
|
||||||
)
|
)
|
||||||
AnimatedVisibility(
|
ManagerLazyColumn {
|
||||||
visible = index == selectedOptionIndex
|
when (installationOption) {
|
||||||
) {
|
is InstallationOption.MultiSelect -> {
|
||||||
ManagerScrollableColumn(
|
items(installationOption.items) { item ->
|
||||||
modifier = Modifier.sizeIn(
|
val preference = installationOption.getOption()
|
||||||
maxHeight = 400.dp
|
CheckboxItem(
|
||||||
)
|
modifier = Modifier.fillMaxWidth(),
|
||||||
) {
|
text = item.displayText(item.key),
|
||||||
when (installationOption) {
|
isChecked = preference.contains(item.key),
|
||||||
is InstallationOption.MultiSelect -> {
|
onCheck = {
|
||||||
installationOption.items.fastForEach { item ->
|
if (it) {
|
||||||
val preference = installationOption.getOption()
|
installationOption.addOption(item.key)
|
||||||
CheckboxItem(
|
} else {
|
||||||
modifier = Modifier.fillMaxWidth(),
|
installationOption.removeOption(item.key)
|
||||||
text = item.displayText(item.key),
|
|
||||||
isChecked = preference.contains(item.key),
|
|
||||||
onCheck = {
|
|
||||||
if (it) {
|
|
||||||
installationOption.addOption(item.key)
|
|
||||||
} else {
|
|
||||||
installationOption.removeOption(item.key)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
is InstallationOption.SingleSelect -> {
|
}
|
||||||
installationOption.items.fastForEach { item ->
|
is InstallationOption.SingleSelect -> {
|
||||||
val preference = installationOption.getOption()
|
items(installationOption.items) { item ->
|
||||||
RadiobuttonItem(
|
val preference = installationOption.getOption()
|
||||||
modifier = Modifier.fillMaxWidth(),
|
RadiobuttonItem(
|
||||||
text = item.displayText(item.key),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
isSelected = preference == item.key,
|
text = item.displayText(item.key),
|
||||||
onSelect = {
|
isSelected = preference == item.key,
|
||||||
installationOption.setOption(item.key)
|
onSelect = {
|
||||||
},
|
installationOption.setOption(item.key)
|
||||||
tag = item.key
|
},
|
||||||
)
|
tag = item.key
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,8 +146,80 @@ fun InstallPreferencesScreen(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(
|
||||||
|
horizontal = DefaultContentPaddingHorizontal,
|
||||||
|
vertical = DefaultContentPaddingVertical
|
||||||
|
),
|
||||||
|
) {
|
||||||
|
AnimatedVisibility(
|
||||||
|
visible = currentOptionIndex > 0
|
||||||
|
) {
|
||||||
|
FloatingActionButton(
|
||||||
|
onClick = {
|
||||||
|
currentOptionIndex--
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Rounded.NavigateBefore,
|
||||||
|
contentDescription = "Back"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
|
AnimatedContent(
|
||||||
|
targetState = currentOptionIndex == installationOptions.lastIndex,
|
||||||
|
transitionSpec = {
|
||||||
|
|
||||||
|
getSlideAnimationSpec(
|
||||||
|
if (initialState && !targetState) {
|
||||||
|
AnimatedContentScope.SlideDirection.Up
|
||||||
|
} else {
|
||||||
|
AnimatedContentScope.SlideDirection.Down
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { lastIndex ->
|
||||||
|
if (lastIndex) {
|
||||||
|
FloatingActionButton(
|
||||||
|
onClick = onDoneClick
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Rounded.Done,
|
||||||
|
contentDescription = "Done"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
FloatingActionButton(
|
||||||
|
onClick = {
|
||||||
|
currentOptionIndex++
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Rounded.NavigateNext,
|
||||||
|
contentDescription = "Next"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExperimentalAnimationApi
|
||||||
}
|
private fun <S> AnimatedContentScope<S>.getSlideAnimationSpec(
|
||||||
|
slideDirection: AnimatedContentScope.SlideDirection
|
||||||
|
) = slideIntoContainer(
|
||||||
|
towards = slideDirection,
|
||||||
|
animationSpec = tween(400)
|
||||||
|
) + fadeIn(
|
||||||
|
animationSpec = tween(400)
|
||||||
|
) with slideOutOfContainer(
|
||||||
|
towards = slideDirection,
|
||||||
|
animationSpec = tween(400)
|
||||||
|
) + fadeOut(
|
||||||
|
animationSpec = tween(400)
|
||||||
|
)
|
|
@ -5,33 +5,37 @@ import androidx.compose.animation.core.animateFloatAsState
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
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.Icon
|
|
||||||
import androidx.compose.material.MaterialTheme
|
|
||||||
import androidx.compose.material.Scaffold
|
|
||||||
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.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.rotate
|
import androidx.compose.ui.draw.rotate
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import androidx.compose.ui.text.SpanStyle
|
import androidx.compose.ui.text.SpanStyle
|
||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.buildAnnotatedString
|
import androidx.compose.ui.text.buildAnnotatedString
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.withStyle
|
import androidx.compose.ui.text.withStyle
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
|
import com.vanced.manager.R
|
||||||
import com.vanced.manager.ui.component.layout.ManagerLazyColumn
|
import com.vanced.manager.ui.component.layout.ManagerLazyColumn
|
||||||
|
import com.vanced.manager.ui.component.layout.ManagerScaffold
|
||||||
import com.vanced.manager.ui.component.modifier.managerClickable
|
import com.vanced.manager.ui.component.modifier.managerClickable
|
||||||
import com.vanced.manager.ui.component.progressindicator.ManagerProgressIndicator
|
import com.vanced.manager.ui.component.progressindicator.ManagerProgressIndicator
|
||||||
import com.vanced.manager.ui.component.text.ManagerText
|
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.util.DefaultContentPaddingVertical
|
|
||||||
import com.vanced.manager.ui.viewmodel.InstallViewModel
|
import com.vanced.manager.ui.viewmodel.InstallViewModel
|
||||||
import org.koin.androidx.compose.getViewModel
|
import org.koin.androidx.compose.getViewModel
|
||||||
|
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
@OptIn(
|
||||||
|
ExperimentalFoundationApi::class,
|
||||||
|
ExperimentalMaterial3Api::class
|
||||||
|
)
|
||||||
@Composable
|
@Composable
|
||||||
fun InstallScreen(
|
fun InstallScreen(
|
||||||
appName: String,
|
appName: String,
|
||||||
|
@ -41,18 +45,12 @@ fun InstallScreen(
|
||||||
|
|
||||||
viewModel.startAppProcess(appName, appVersions)
|
viewModel.startAppProcess(appName, appVersions)
|
||||||
|
|
||||||
Scaffold(
|
ManagerScaffold(
|
||||||
floatingActionButton = {
|
topBar = {
|
||||||
|
Column {
|
||||||
}
|
ManagerTopAppBar(
|
||||||
) { paddingValues ->
|
title = managerString(R.string.toolbar_install),
|
||||||
ManagerLazyColumn(
|
)
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(paddingValues),
|
|
||||||
contentPadding = PaddingValues(0.dp),
|
|
||||||
) {
|
|
||||||
stickyHeader {
|
|
||||||
when (val status = viewModel.status) {
|
when (val status = viewModel.status) {
|
||||||
is InstallViewModel.Status.Progress -> {
|
is InstallViewModel.Status.Progress -> {
|
||||||
ManagerProgressIndicator(status.progress)
|
ManagerProgressIndicator(status.progress)
|
||||||
|
@ -63,11 +61,16 @@ fun InstallScreen(
|
||||||
else -> {}
|
else -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
floatingActionButton = {
|
||||||
|
|
||||||
item {
|
}
|
||||||
Spacer(Modifier.height(DefaultContentPaddingVertical))
|
) { paddingValues ->
|
||||||
}
|
ManagerLazyColumn(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(paddingValues),
|
||||||
|
) {
|
||||||
items(viewModel.logs) { log ->
|
items(viewModel.logs) { log ->
|
||||||
when (log) {
|
when (log) {
|
||||||
is InstallViewModel.Log.Success -> {
|
is InstallViewModel.Log.Success -> {
|
||||||
|
@ -79,7 +82,7 @@ fun InstallScreen(
|
||||||
textStyle = TextStyle(
|
textStyle = TextStyle(
|
||||||
fontWeight = FontWeight.Bold,
|
fontWeight = FontWeight.Bold,
|
||||||
fontSize = 14.sp,
|
fontSize = 14.sp,
|
||||||
color = Color.Blue
|
color = MaterialTheme.colorScheme.tertiary
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -92,7 +95,7 @@ fun InstallScreen(
|
||||||
textStyle = TextStyle(
|
textStyle = TextStyle(
|
||||||
fontWeight = FontWeight.SemiBold,
|
fontWeight = FontWeight.SemiBold,
|
||||||
fontSize = 14.sp,
|
fontSize = 14.sp,
|
||||||
color = Color.Black
|
color = MaterialTheme.colorScheme.onSurface
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -114,7 +117,7 @@ fun InstallScreen(
|
||||||
) {
|
) {
|
||||||
ManagerText(
|
ManagerText(
|
||||||
text = buildAnnotatedString {
|
text = buildAnnotatedString {
|
||||||
withStyle(SpanStyle(color = MaterialTheme.colors.error)) {
|
withStyle(SpanStyle(color = MaterialTheme.colorScheme.error)) {
|
||||||
append(log.displayText)
|
append(log.displayText)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -127,7 +130,7 @@ fun InstallScreen(
|
||||||
modifier = Modifier.rotate(iconRotation),
|
modifier = Modifier.rotate(iconRotation),
|
||||||
imageVector = Icons.Rounded.ArrowDropDown,
|
imageVector = Icons.Rounded.ArrowDropDown,
|
||||||
contentDescription = "expand",
|
contentDescription = "expand",
|
||||||
tint = MaterialTheme.colors.error
|
tint = MaterialTheme.colorScheme.error
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
AnimatedVisibility(visible) {
|
AnimatedVisibility(visible) {
|
||||||
|
@ -136,7 +139,7 @@ fun InstallScreen(
|
||||||
textStyle = TextStyle(
|
textStyle = TextStyle(
|
||||||
fontWeight = FontWeight.Bold,
|
fontWeight = FontWeight.Bold,
|
||||||
fontSize = 14.sp,
|
fontSize = 14.sp,
|
||||||
color = MaterialTheme.colors.error.copy(alpha = 0.7f)
|
color = MaterialTheme.colorScheme.error.copy(alpha = 0.7f)
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
package com.vanced.manager.ui.screens
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.lazy.items
|
|
||||||
import androidx.compose.material.FloatingActionButton
|
|
||||||
import androidx.compose.material.Icon
|
|
||||||
import androidx.compose.material.Scaffold
|
|
||||||
import androidx.compose.material.Text
|
|
||||||
import androidx.compose.material.icons.Icons
|
|
||||||
import androidx.compose.material.icons.filled.Share
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import com.vanced.manager.ui.component.color.managerAccentColor
|
|
||||||
import com.vanced.manager.ui.component.color.managerSurfaceColor
|
|
||||||
import com.vanced.manager.ui.component.layout.ManagerLazyColumn
|
|
||||||
import com.vanced.manager.core.util.logs
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun LogLayout() {
|
|
||||||
Scaffold(
|
|
||||||
modifier = Modifier.fillMaxSize(),
|
|
||||||
floatingActionButton = {
|
|
||||||
FloatingActionButton(
|
|
||||||
onClick = { /*TODO*/ },
|
|
||||||
backgroundColor = managerAccentColor()
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Default.Share,
|
|
||||||
contentDescription = "share"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
backgroundColor = managerSurfaceColor()
|
|
||||||
) {
|
|
||||||
ManagerLazyColumn {
|
|
||||||
items(logs) { log ->
|
|
||||||
Text(text = log.body)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,37 +1,59 @@
|
||||||
package com.vanced.manager.ui.screens
|
package com.vanced.manager.ui.screens
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
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.runtime.Composable
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.Modifier
|
||||||
import com.vanced.manager.R
|
import com.vanced.manager.R
|
||||||
import com.vanced.manager.ui.component.layout.ManagerScrollableColumn
|
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.resources.managerString
|
||||||
import com.vanced.manager.ui.util.DefaultContentPaddingVertical
|
import com.vanced.manager.ui.util.Screen
|
||||||
import com.vanced.manager.ui.widget.layout.SettingsCategoryLayout
|
import com.vanced.manager.ui.widget.layout.managerCategory
|
||||||
import com.vanced.manager.ui.widget.screens.settings.*
|
import com.vanced.manager.ui.widget.screens.settings.*
|
||||||
|
|
||||||
|
@ExperimentalMaterial3Api
|
||||||
@Composable
|
@Composable
|
||||||
fun SettingsLayout() {
|
fun SettingsLayout(
|
||||||
ManagerScrollableColumn(
|
onToolbarBackButtonClick: () -> Unit,
|
||||||
contentPaddingVertical = DefaultContentPaddingVertical,
|
) {
|
||||||
itemSpacing = 12.dp
|
val settingsCategoryBehaviour = managerString(R.string.settings_category_behaviour)
|
||||||
) {
|
val settingsCategoryApperance = managerString(R.string.settings_category_appearance)
|
||||||
SettingsCategoryLayout(
|
|
||||||
categoryName = managerString(
|
Scaffold(
|
||||||
stringId = R.string.settings_category_behaviour
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
topBar = {
|
||||||
|
ManagerTopAppBar(
|
||||||
|
title = managerString(Screen.Settings.displayName),
|
||||||
|
navigationIcon = {
|
||||||
|
IconButton(onClick = onToolbarBackButtonClick) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Rounded.ArrowBackIosNew,
|
||||||
|
contentDescription = "Back"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
) {
|
|
||||||
SettingsCustomTabsItem()
|
|
||||||
SettingsNotificationsItem()
|
|
||||||
SettingsManagerVariantItem()
|
|
||||||
}
|
}
|
||||||
SettingsCategoryLayout(
|
) { paddingValues ->
|
||||||
categoryName = managerString(
|
ManagerLazyColumn(
|
||||||
stringId = R.string.settings_category_appearance
|
modifier = Modifier.fillMaxSize().padding(paddingValues),
|
||||||
)
|
|
||||||
) {
|
) {
|
||||||
SettingsAccentColorItem()
|
managerCategory(settingsCategoryBehaviour) {
|
||||||
ThemeSettingsItem()
|
SettingsCustomTabsItem()
|
||||||
|
SettingsNotificationsItem()
|
||||||
|
SettingsManagerVariantItem()
|
||||||
|
}
|
||||||
|
managerCategory(settingsCategoryApperance) {
|
||||||
|
SettingsAccentColorItem()
|
||||||
|
ThemeSettingsItem()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -9,4 +9,59 @@ val darkSurface = Color.Black
|
||||||
val darkOnSurface = Color(0xFFD5D5D5)
|
val darkOnSurface = Color(0xFFD5D5D5)
|
||||||
|
|
||||||
val lightSurface = Color.White
|
val lightSurface = Color.White
|
||||||
val lightOnSurface = Color.Black
|
val lightOnSurface = Color.Black
|
||||||
|
|
||||||
|
val md_theme_light_primary = Color(0xFF0054d9)
|
||||||
|
val md_theme_light_onPrimary = Color(0xFFffffff)
|
||||||
|
val md_theme_light_primaryContainer = Color(0xFFdae2ff)
|
||||||
|
val md_theme_light_onPrimaryContainer = Color(0xFF00174a)
|
||||||
|
val md_theme_light_secondary = Color(0xFFc00020)
|
||||||
|
val md_theme_light_onSecondary = Color(0xFFffffff)
|
||||||
|
val md_theme_light_secondaryContainer = Color(0xFFffdad6)
|
||||||
|
val md_theme_light_onSecondaryContainer = Color(0xFF410005)
|
||||||
|
val md_theme_light_tertiary = Color(0xFF943896)
|
||||||
|
val md_theme_light_onTertiary = Color(0xFFffffff)
|
||||||
|
val md_theme_light_tertiaryContainer = Color(0xFFffd6fa)
|
||||||
|
val md_theme_light_onTertiaryContainer = Color(0xFF37003c)
|
||||||
|
val md_theme_light_error = Color(0xFFba1b1b)
|
||||||
|
val md_theme_light_errorContainer = Color(0xFFffdad4)
|
||||||
|
val md_theme_light_onError = Color(0xFFffffff)
|
||||||
|
val md_theme_light_onErrorContainer = Color(0xFF410001)
|
||||||
|
val md_theme_light_background = Color(0xFFfefbff)
|
||||||
|
val md_theme_light_onBackground = Color(0xFF1b1b1e)
|
||||||
|
val md_theme_light_surface = Color(0xFFfefbff)
|
||||||
|
val md_theme_light_onSurface = Color(0xFF1b1b1e)
|
||||||
|
val md_theme_light_surfaceVariant = Color(0xFFe2e2ec)
|
||||||
|
val md_theme_light_onSurfaceVariant = Color(0xFF44464e)
|
||||||
|
val md_theme_light_outline = Color(0xFF75767f)
|
||||||
|
val md_theme_light_inverseOnSurface = Color(0xFFf2f0f5)
|
||||||
|
val md_theme_light_inverseSurface = Color(0xFF303033)
|
||||||
|
|
||||||
|
val md_theme_dark_primary = Color(0xFFb1c5ff)
|
||||||
|
val md_theme_dark_onPrimary = Color(0xFF002a77)
|
||||||
|
val md_theme_dark_primaryContainer = Color(0xFF003ea6)
|
||||||
|
val md_theme_dark_onPrimaryContainer = Color(0xFFdae2ff)
|
||||||
|
val md_theme_dark_secondary = Color(0xFFffb3af)
|
||||||
|
val md_theme_dark_onSecondary = Color(0xFF69000c)
|
||||||
|
val md_theme_dark_secondaryContainer = Color(0xFF920016)
|
||||||
|
val md_theme_dark_onSecondaryContainer = Color(0xFFffdad6)
|
||||||
|
val md_theme_dark_tertiary = Color(0xFFffa9fc)
|
||||||
|
val md_theme_dark_onTertiary = Color(0xFF5a0061)
|
||||||
|
val md_theme_dark_tertiaryContainer = Color(0xFF781c7c)
|
||||||
|
val md_theme_dark_onTertiaryContainer = Color(0xFFffd6fa)
|
||||||
|
val md_theme_dark_error = Color(0xFFffb4a9)
|
||||||
|
val md_theme_dark_errorContainer = Color(0xFF930006)
|
||||||
|
val md_theme_dark_onError = Color(0xFF680003)
|
||||||
|
val md_theme_dark_onErrorContainer = Color(0xFFffdad4)
|
||||||
|
val md_theme_dark_background = Color(0xFF1b1b1e)
|
||||||
|
val md_theme_dark_onBackground = Color(0xFFe3e1e6)
|
||||||
|
val md_theme_dark_surface = Color(0xFF1b1b1e)
|
||||||
|
val md_theme_dark_onSurface = Color(0xFFe3e1e6)
|
||||||
|
val md_theme_dark_surfaceVariant = Color(0xFF44464e)
|
||||||
|
val md_theme_dark_onSurfaceVariant = Color(0xFFc6c6d0)
|
||||||
|
val md_theme_dark_outline = Color(0xFF8f909a)
|
||||||
|
val md_theme_dark_inverseOnSurface = Color(0xFF1b1b1e)
|
||||||
|
val md_theme_dark_inverseSurface = Color(0xFFe3e1e6)
|
||||||
|
|
||||||
|
val seed = Color(0xFF2e73ff)
|
||||||
|
val error = Color(0xFFba1b1b)
|
|
@ -1,11 +1,9 @@
|
||||||
package com.vanced.manager.ui.theme
|
package com.vanced.manager.ui.theme
|
||||||
|
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material.Shapes
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
||||||
val shapes = Shapes(
|
//TODO M3 doesn't support Shapes yet
|
||||||
small = RoundedCornerShape(8.dp),
|
val SmallShape = RoundedCornerShape(8.dp)
|
||||||
medium = RoundedCornerShape(12.dp),
|
val MediumShape = RoundedCornerShape(12.dp)
|
||||||
large = RoundedCornerShape(8.dp)
|
val LargeShape = RoundedCornerShape(16.dp)
|
||||||
)
|
|
|
@ -1,26 +1,74 @@
|
||||||
package com.vanced.manager.ui.theme
|
package com.vanced.manager.ui.theme
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
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.OverScrollConfiguration
|
||||||
import androidx.compose.foundation.isSystemInDarkTheme
|
import androidx.compose.foundation.isSystemInDarkTheme
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material.ripple.rememberRipple
|
||||||
import androidx.compose.material.darkColors
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.material.lightColors
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import com.vanced.manager.core.preferences.holder.managerThemePref
|
import com.vanced.manager.core.preferences.holder.managerThemePref
|
||||||
|
|
||||||
const val defAccentColor = 0xFF0477E1
|
const val defAccentColor = 0xFF0477E1
|
||||||
|
|
||||||
private val DarkColorPalette = darkColors(
|
private val LightThemeColors = lightColorScheme(
|
||||||
primary = primaryColor,
|
primary = md_theme_light_primary,
|
||||||
primaryVariant = primaryColorVariant,
|
onPrimary = md_theme_light_onPrimary,
|
||||||
surface = darkSurface,
|
primaryContainer = md_theme_light_primaryContainer,
|
||||||
onSurface = darkOnSurface
|
onPrimaryContainer = md_theme_light_onPrimaryContainer,
|
||||||
|
secondary = md_theme_light_secondary,
|
||||||
|
onSecondary = md_theme_light_onSecondary,
|
||||||
|
secondaryContainer = md_theme_light_secondaryContainer,
|
||||||
|
onSecondaryContainer = md_theme_light_onSecondaryContainer,
|
||||||
|
tertiary = md_theme_light_tertiary,
|
||||||
|
onTertiary = md_theme_light_onTertiary,
|
||||||
|
tertiaryContainer = md_theme_light_tertiaryContainer,
|
||||||
|
onTertiaryContainer = md_theme_light_onTertiaryContainer,
|
||||||
|
error = md_theme_light_error,
|
||||||
|
errorContainer = md_theme_light_errorContainer,
|
||||||
|
onError = md_theme_light_onError,
|
||||||
|
onErrorContainer = md_theme_light_onErrorContainer,
|
||||||
|
background = md_theme_light_background,
|
||||||
|
onBackground = md_theme_light_onBackground,
|
||||||
|
surface = md_theme_light_surface,
|
||||||
|
onSurface = md_theme_light_onSurface,
|
||||||
|
surfaceVariant = md_theme_light_surfaceVariant,
|
||||||
|
onSurfaceVariant = md_theme_light_onSurfaceVariant,
|
||||||
|
outline = md_theme_light_outline,
|
||||||
|
inverseOnSurface = md_theme_light_inverseOnSurface,
|
||||||
|
inverseSurface = md_theme_light_inverseSurface,
|
||||||
)
|
)
|
||||||
|
private val DarkThemeColors = darkColorScheme(
|
||||||
private val LightColorPalette = lightColors(
|
primary = md_theme_dark_primary,
|
||||||
primary = primaryColor,
|
onPrimary = md_theme_dark_onPrimary,
|
||||||
primaryVariant = primaryColorVariant,
|
primaryContainer = md_theme_dark_primaryContainer,
|
||||||
surface = lightSurface,
|
onPrimaryContainer = md_theme_dark_onPrimaryContainer,
|
||||||
onSurface = lightOnSurface,
|
secondary = md_theme_dark_secondary,
|
||||||
|
onSecondary = md_theme_dark_onSecondary,
|
||||||
|
secondaryContainer = md_theme_dark_secondaryContainer,
|
||||||
|
onSecondaryContainer = md_theme_dark_onSecondaryContainer,
|
||||||
|
tertiary = md_theme_dark_tertiary,
|
||||||
|
onTertiary = md_theme_dark_onTertiary,
|
||||||
|
tertiaryContainer = md_theme_dark_tertiaryContainer,
|
||||||
|
onTertiaryContainer = md_theme_dark_onTertiaryContainer,
|
||||||
|
error = md_theme_dark_error,
|
||||||
|
errorContainer = md_theme_dark_errorContainer,
|
||||||
|
onError = md_theme_dark_onError,
|
||||||
|
onErrorContainer = md_theme_dark_onErrorContainer,
|
||||||
|
background = md_theme_dark_background,
|
||||||
|
onBackground = md_theme_dark_onBackground,
|
||||||
|
surface = md_theme_dark_surface,
|
||||||
|
onSurface = md_theme_dark_onSurface,
|
||||||
|
surfaceVariant = md_theme_dark_surfaceVariant,
|
||||||
|
onSurfaceVariant = md_theme_dark_onSurfaceVariant,
|
||||||
|
outline = md_theme_dark_outline,
|
||||||
|
inverseOnSurface = md_theme_dark_inverseOnSurface,
|
||||||
|
inverseSurface = md_theme_dark_inverseSurface,
|
||||||
)
|
)
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
@ -31,16 +79,41 @@ fun isDark(): Boolean = when (managerThemePref.value.value) {
|
||||||
else -> throw IllegalArgumentException("Unknown theme")
|
else -> throw IllegalArgumentException("Unknown theme")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("NewApi")
|
||||||
|
@ExperimentalFoundationApi
|
||||||
@Composable
|
@Composable
|
||||||
fun ManagerTheme(
|
fun ManagerTheme(
|
||||||
content: @Composable () -> Unit
|
content: @Composable () -> Unit
|
||||||
) {
|
) {
|
||||||
val colors = if (isDark()) DarkColorPalette else LightColorPalette
|
val isAndroid12OrHigher = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
|
||||||
|
val colorScheme =
|
||||||
|
if (isAndroid12OrHigher) {
|
||||||
|
val context = LocalContext.current
|
||||||
|
if (isDark()) {
|
||||||
|
dynamicDarkColorScheme(context)
|
||||||
|
} else {
|
||||||
|
dynamicLightColorScheme(context)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (isDark()) {
|
||||||
|
DarkThemeColors
|
||||||
|
} else {
|
||||||
|
LightThemeColors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MaterialTheme(
|
MaterialTheme(
|
||||||
colors = colors,
|
colorScheme = colorScheme,
|
||||||
typography = typography,
|
typography = ManagerTypography,
|
||||||
shapes = shapes,
|
) {
|
||||||
content = content
|
val rippleIndication = rememberRipple()
|
||||||
)
|
CompositionLocalProvider(
|
||||||
|
LocalIndication provides rippleIndication,
|
||||||
|
LocalOverScrollConfiguration provides OverScrollConfiguration(
|
||||||
|
forceShowAlways = isAndroid12OrHigher
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
content()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
package com.vanced.manager.ui.theme
|
package com.vanced.manager.ui.theme
|
||||||
|
|
||||||
import androidx.compose.material.Typography
|
import androidx.compose.material3.Typography
|
||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.font.Font
|
import androidx.compose.ui.text.font.Font
|
||||||
import androidx.compose.ui.text.font.FontFamily
|
import androidx.compose.ui.text.font.FontFamily
|
||||||
|
@ -14,45 +14,112 @@ private val medium = Font(R.font.inter_medium, FontWeight.Medium)
|
||||||
private val semibold = Font(R.font.inter_semibold, FontWeight.SemiBold)
|
private val semibold = Font(R.font.inter_semibold, FontWeight.SemiBold)
|
||||||
private val bold = Font(R.font.inter_bold, FontWeight.Bold)
|
private val bold = Font(R.font.inter_bold, FontWeight.Bold)
|
||||||
|
|
||||||
private val interFontFamily = FontFamily(light, regular, medium, semibold, bold)
|
private val InterFontFamily = FontFamily(light, regular, medium, semibold, bold)
|
||||||
|
|
||||||
// Set of Material typography styles to start with
|
val ManagerTypography = Typography(
|
||||||
val typography = Typography(
|
displayLarge = TextStyle(
|
||||||
defaultFontFamily = interFontFamily,
|
fontFamily = InterFontFamily,
|
||||||
h1 = TextStyle(
|
|
||||||
fontSize = 24.sp,
|
|
||||||
fontWeight = FontWeight.Bold,
|
|
||||||
),
|
|
||||||
h2 = TextStyle(
|
|
||||||
fontSize = 20.sp,
|
|
||||||
fontWeight = FontWeight.SemiBold
|
|
||||||
),
|
|
||||||
h5 = TextStyle(
|
|
||||||
fontSize = 16.sp,
|
|
||||||
fontWeight = FontWeight.SemiBold,
|
|
||||||
),
|
|
||||||
h6 = TextStyle(
|
|
||||||
fontSize = 14.sp,
|
|
||||||
fontWeight = FontWeight.Bold
|
|
||||||
),
|
|
||||||
body1 = TextStyle(
|
|
||||||
fontWeight = FontWeight.Medium,
|
|
||||||
fontSize = 12.sp
|
|
||||||
),
|
|
||||||
body2 = TextStyle(
|
|
||||||
fontWeight = FontWeight.Normal,
|
fontWeight = FontWeight.Normal,
|
||||||
fontSize = 10.sp,
|
fontSize = 57.sp,
|
||||||
|
lineHeight = 64.sp,
|
||||||
|
letterSpacing = (-0.25).sp,
|
||||||
),
|
),
|
||||||
subtitle1 = TextStyle(
|
displayMedium = TextStyle(
|
||||||
|
fontFamily = InterFontFamily,
|
||||||
|
fontWeight = FontWeight.Normal,
|
||||||
|
fontSize = 45.sp,
|
||||||
|
lineHeight = 52.sp,
|
||||||
|
letterSpacing = 0.sp,
|
||||||
|
),
|
||||||
|
displaySmall = TextStyle(
|
||||||
|
fontFamily = InterFontFamily,
|
||||||
|
fontWeight = FontWeight.Normal,
|
||||||
|
fontSize = 36.sp,
|
||||||
|
lineHeight = 44.sp,
|
||||||
|
letterSpacing = 0.sp,
|
||||||
|
),
|
||||||
|
headlineLarge = TextStyle(
|
||||||
|
fontFamily = InterFontFamily,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
fontSize = 32.sp,
|
||||||
|
lineHeight = 40.sp,
|
||||||
|
letterSpacing = 0.sp,
|
||||||
|
),
|
||||||
|
headlineMedium = TextStyle(
|
||||||
|
fontFamily = InterFontFamily,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
fontSize = 28.sp,
|
||||||
|
lineHeight = 36.sp,
|
||||||
|
letterSpacing = 0.sp,
|
||||||
|
),
|
||||||
|
headlineSmall = TextStyle(
|
||||||
|
fontFamily = InterFontFamily,
|
||||||
|
fontWeight = FontWeight.SemiBold,
|
||||||
|
fontSize = 24.sp,
|
||||||
|
lineHeight = 32.sp,
|
||||||
|
letterSpacing = 0.sp,
|
||||||
|
),
|
||||||
|
titleLarge = TextStyle(
|
||||||
|
fontFamily = InterFontFamily,
|
||||||
|
fontWeight = FontWeight.SemiBold,
|
||||||
|
fontSize = 22.sp,
|
||||||
|
lineHeight = 28.sp,
|
||||||
|
letterSpacing = 0.sp,
|
||||||
|
),
|
||||||
|
titleMedium = TextStyle(
|
||||||
|
fontFamily = InterFontFamily,
|
||||||
|
fontWeight = FontWeight.SemiBold,
|
||||||
|
fontSize = 18.sp,
|
||||||
|
lineHeight = 24.sp,
|
||||||
|
letterSpacing = 0.1.sp,
|
||||||
|
),
|
||||||
|
titleSmall = TextStyle(
|
||||||
|
fontFamily = InterFontFamily,
|
||||||
|
fontWeight = FontWeight.SemiBold,
|
||||||
|
fontSize = 16.sp,
|
||||||
|
lineHeight = 20.sp,
|
||||||
|
letterSpacing = 0.1.sp,
|
||||||
|
),
|
||||||
|
bodyLarge = TextStyle(
|
||||||
|
fontFamily = InterFontFamily,
|
||||||
|
fontWeight = FontWeight.Normal,
|
||||||
|
fontSize = 16.sp,
|
||||||
|
lineHeight = 24.sp,
|
||||||
|
letterSpacing = 0.5.sp,
|
||||||
|
),
|
||||||
|
bodyMedium = TextStyle(
|
||||||
|
fontFamily = InterFontFamily,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
fontSize = 14.sp,
|
||||||
|
lineHeight = 20.sp,
|
||||||
|
letterSpacing = 0.25.sp,
|
||||||
|
),
|
||||||
|
bodySmall = TextStyle(
|
||||||
|
fontFamily = InterFontFamily,
|
||||||
fontWeight = FontWeight.Normal,
|
fontWeight = FontWeight.Normal,
|
||||||
fontSize = 12.sp,
|
fontSize = 12.sp,
|
||||||
|
lineHeight = 14.sp,
|
||||||
|
letterSpacing = 0.sp,
|
||||||
),
|
),
|
||||||
subtitle2 = TextStyle(
|
labelLarge = TextStyle(
|
||||||
fontWeight = FontWeight.Normal,
|
fontFamily = InterFontFamily,
|
||||||
fontSize = 14.sp
|
fontWeight = FontWeight.SemiBold,
|
||||||
),
|
|
||||||
button = TextStyle(
|
|
||||||
fontSize = 14.sp,
|
fontSize = 14.sp,
|
||||||
fontWeight = FontWeight.Medium
|
lineHeight = 20.sp,
|
||||||
)
|
letterSpacing = 0.1.sp,
|
||||||
|
),
|
||||||
|
labelMedium = TextStyle(
|
||||||
|
fontFamily = InterFontFamily,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
fontSize = 12.sp,
|
||||||
|
lineHeight = 16.sp,
|
||||||
|
letterSpacing = 0.5.sp,
|
||||||
|
),
|
||||||
|
labelSmall = TextStyle(
|
||||||
|
fontFamily = InterFontFamily,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
fontSize = 11.sp,
|
||||||
|
lineHeight = 16.sp,
|
||||||
|
letterSpacing = 0.5.sp,
|
||||||
|
),
|
||||||
)
|
)
|
|
@ -1,13 +1,8 @@
|
||||||
package com.vanced.manager.ui.util
|
package com.vanced.manager.ui.util
|
||||||
|
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
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.screens.AboutLayout
|
|
||||||
import com.vanced.manager.ui.screens.HomeLayout
|
|
||||||
import com.vanced.manager.ui.screens.LogLayout
|
|
||||||
import com.vanced.manager.ui.screens.SettingsLayout
|
|
||||||
|
|
||||||
sealed class Screen(
|
sealed class Screen(
|
||||||
val route: String,
|
val route: String,
|
||||||
|
|
|
@ -3,13 +3,10 @@ package com.vanced.manager.ui.viewmodel
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
|
||||||
import com.vanced.manager.core.downloader.base.AppDownloader
|
|
||||||
import com.vanced.manager.core.downloader.util.DownloadStatus
|
|
||||||
import com.vanced.manager.domain.model.App
|
|
||||||
import com.vanced.manager.core.preferences.holder.managerVariantPref
|
import com.vanced.manager.core.preferences.holder.managerVariantPref
|
||||||
import com.vanced.manager.core.preferences.holder.musicEnabled
|
import com.vanced.manager.core.preferences.holder.musicEnabled
|
||||||
import com.vanced.manager.core.preferences.holder.vancedEnabled
|
import com.vanced.manager.core.preferences.holder.vancedEnabled
|
||||||
|
import com.vanced.manager.domain.model.App
|
||||||
import com.vanced.manager.repository.JsonRepository
|
import com.vanced.manager.repository.JsonRepository
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
@ -34,7 +31,7 @@ class MainViewModel(
|
||||||
val appState: StateFlow<AppState> = _appState
|
val appState: StateFlow<AppState> = _appState
|
||||||
|
|
||||||
fun fetch() {
|
fun fetch() {
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch {
|
||||||
val vancedEnabled = vancedEnabled.value.value
|
val vancedEnabled = vancedEnabled.value.value
|
||||||
val musicEnabled = musicEnabled.value.value
|
val musicEnabled = musicEnabled.value.value
|
||||||
val isNonroot = managerVariantPref.value.value == "nonroot"
|
val isNonroot = managerVariantPref.value.value == "nonroot"
|
||||||
|
|
|
@ -4,19 +4,22 @@ import androidx.compose.animation.ExperimentalAnimationApi
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.material.MaterialTheme
|
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.Info
|
||||||
import androidx.compose.material.icons.outlined.Info
|
import androidx.compose.material.icons.outlined.Info
|
||||||
import androidx.compose.material.icons.rounded.DeleteForever
|
import androidx.compose.material.icons.rounded.DeleteForever
|
||||||
import androidx.compose.material.icons.rounded.Download
|
import androidx.compose.material.icons.rounded.Download
|
||||||
import androidx.compose.material.icons.rounded.Launch
|
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.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import coil.compose.ImagePainter
|
import coil.compose.ImagePainter
|
||||||
import com.vanced.manager.R
|
import com.vanced.manager.R
|
||||||
import com.vanced.manager.ui.component.button.IconButton
|
import com.vanced.manager.ui.component.button.ManagerIconButton
|
||||||
import com.vanced.manager.ui.component.text.AppVersionText
|
import com.vanced.manager.ui.component.text.AppVersionText
|
||||||
import com.vanced.manager.ui.component.text.ManagerText
|
import com.vanced.manager.ui.component.text.ManagerText
|
||||||
|
|
||||||
|
@ -27,17 +30,17 @@ fun AppCard(
|
||||||
appIcon: ImagePainter,
|
appIcon: ImagePainter,
|
||||||
appInstalledVersion: String?,
|
appInstalledVersion: String?,
|
||||||
appRemoteVersion: String?,
|
appRemoteVersion: String?,
|
||||||
onDownloadClick: () -> Unit,
|
onAppDownloadClick: () -> Unit,
|
||||||
onUninstallClick: () -> Unit,
|
onAppUninstallClick: () -> Unit,
|
||||||
onLaunchClick: () -> Unit,
|
onAppLaunchClick: () -> Unit,
|
||||||
onInfoClick: () -> Unit,
|
onAppInfoClick: () -> Unit,
|
||||||
) {
|
) {
|
||||||
BaseAppCard(
|
BaseAppCard(
|
||||||
appTitle = {
|
appTitle = {
|
||||||
ManagerText(
|
ManagerText(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
text = appName,
|
text = appName,
|
||||||
textStyle = MaterialTheme.typography.h5
|
textStyle = MaterialTheme.typography.titleMedium
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
appIcon = {
|
appIcon = {
|
||||||
|
@ -47,6 +50,14 @@ fun AppCard(
|
||||||
contentDescription = "App Icon",
|
contentDescription = "App Icon",
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
appTrailing = {
|
||||||
|
IconButton(onClick = onAppInfoClick) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Outlined.Info,
|
||||||
|
contentDescription = "App Info"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
appVersionsColumn = {
|
appVersionsColumn = {
|
||||||
AppVersionText(
|
AppVersionText(
|
||||||
text = stringResource(
|
text = stringResource(
|
||||||
|
@ -66,26 +77,24 @@ fun AppCard(
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
appActionsRow = {
|
appActionsRow = {
|
||||||
IconButton(
|
IconButton(onClick = onAppUninstallClick) {
|
||||||
icon = Icons.Outlined.Info,
|
Icon(
|
||||||
contentDescription = "App Info",
|
imageVector = Icons.Rounded.DeleteForever,
|
||||||
onClick = onInfoClick
|
contentDescription = "Uninstall"
|
||||||
)
|
)
|
||||||
IconButton(
|
}
|
||||||
icon = Icons.Rounded.DeleteForever,
|
IconButton(onClick = onAppLaunchClick) {
|
||||||
contentDescription = "Uninstall",
|
Icon(
|
||||||
onClick = onUninstallClick
|
imageVector = Icons.Rounded.Launch,
|
||||||
)
|
contentDescription = "Launch",
|
||||||
IconButton(
|
)
|
||||||
icon = Icons.Rounded.Launch,
|
}
|
||||||
contentDescription = "Launch",
|
IconButton(onClick = onAppDownloadClick) {
|
||||||
onClick = onLaunchClick
|
Icon(
|
||||||
)
|
imageVector = Icons.Rounded.Download,
|
||||||
IconButton(
|
contentDescription = "Install",
|
||||||
icon = Icons.Rounded.Download,
|
)
|
||||||
contentDescription = "Install",
|
}
|
||||||
onClick = onDownloadClick
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
|
@ -1,7 +1,12 @@
|
||||||
package com.vanced.manager.ui.widget.app
|
package com.vanced.manager.ui.widget.app
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.material.MaterialTheme
|
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.IconButton
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
|
@ -9,6 +14,8 @@ import androidx.compose.ui.unit.dp
|
||||||
import com.vanced.manager.ui.component.modifier.managerPlaceholder
|
import com.vanced.manager.ui.component.modifier.managerPlaceholder
|
||||||
import com.vanced.manager.ui.component.text.AppVersionText
|
import com.vanced.manager.ui.component.text.AppVersionText
|
||||||
import com.vanced.manager.ui.component.text.ManagerText
|
import com.vanced.manager.ui.component.text.ManagerText
|
||||||
|
import com.vanced.manager.ui.theme.MediumShape
|
||||||
|
import com.vanced.manager.ui.theme.SmallShape
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun AppCardPlaceholder() {
|
fun AppCardPlaceholder() {
|
||||||
|
@ -16,38 +23,46 @@ fun AppCardPlaceholder() {
|
||||||
appTitle = {
|
appTitle = {
|
||||||
ManagerText(
|
ManagerText(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.clip(MaterialTheme.shapes.medium)
|
.clip(MediumShape)
|
||||||
.managerPlaceholder(true),
|
.managerPlaceholder(true),
|
||||||
text = " ".repeat(40),
|
text = " ".repeat(40),
|
||||||
textStyle = MaterialTheme.typography.h5
|
textStyle = MaterialTheme.typography.titleMedium
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
appIcon = {
|
appIcon = {
|
||||||
Box(
|
Box(
|
||||||
Modifier
|
Modifier
|
||||||
.clip(MaterialTheme.shapes.medium)
|
.clip(MediumShape)
|
||||||
.managerPlaceholder(true)
|
.managerPlaceholder(true)
|
||||||
.size(48.dp)
|
.size(48.dp)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
appTrailing = {
|
||||||
|
Box(
|
||||||
|
Modifier
|
||||||
|
.clip(CircleShape)
|
||||||
|
.managerPlaceholder(true)
|
||||||
|
.size(24.dp)
|
||||||
|
)
|
||||||
|
},
|
||||||
appVersionsColumn = {
|
appVersionsColumn = {
|
||||||
AppVersionText(
|
AppVersionText(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.managerPlaceholder(true)
|
.managerPlaceholder(true)
|
||||||
.clip(MaterialTheme.shapes.small),
|
.clip(SmallShape),
|
||||||
text = " ".repeat(30)
|
text = " ".repeat(30)
|
||||||
)
|
)
|
||||||
AppVersionText(
|
AppVersionText(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.managerPlaceholder(true)
|
.managerPlaceholder(true)
|
||||||
.clip(MaterialTheme.shapes.small),
|
.clip(SmallShape),
|
||||||
text = " ".repeat(30)
|
text = " ".repeat(30)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
appActionsRow = {
|
appActionsRow = {
|
||||||
Box(
|
Box(
|
||||||
Modifier
|
Modifier
|
||||||
.clip(MaterialTheme.shapes.medium)
|
.clip(MediumShape)
|
||||||
.fillMaxWidth(0.8f)
|
.fillMaxWidth(0.8f)
|
||||||
.height(36.dp)
|
.height(36.dp)
|
||||||
.managerPlaceholder(true)
|
.managerPlaceholder(true)
|
||||||
|
|
|
@ -1,19 +1,21 @@
|
||||||
package com.vanced.manager.ui.widget.app
|
package com.vanced.manager.ui.widget.app
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.material.LocalContentColor
|
import androidx.compose.material.Divider
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material3.LocalContentColor
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
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.draw.clip
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.vanced.manager.R
|
import com.vanced.manager.R
|
||||||
import com.vanced.manager.ui.component.card.ManagerCard
|
import com.vanced.manager.ui.component.card.ManagerTonalCard
|
||||||
import com.vanced.manager.ui.component.card.ManagerThemedCard
|
|
||||||
import com.vanced.manager.ui.component.list.ManagerListItem
|
import com.vanced.manager.ui.component.list.ManagerListItem
|
||||||
import com.vanced.manager.ui.component.text.ManagerText
|
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.DefaultContentPaddingHorizontal
|
||||||
import com.vanced.manager.ui.util.DefaultContentPaddingVertical
|
import com.vanced.manager.ui.util.DefaultContentPaddingVertical
|
||||||
|
|
||||||
|
@ -21,48 +23,59 @@ import com.vanced.manager.ui.util.DefaultContentPaddingVertical
|
||||||
fun BaseAppCard(
|
fun BaseAppCard(
|
||||||
appTitle: @Composable () -> Unit,
|
appTitle: @Composable () -> Unit,
|
||||||
appIcon: @Composable () -> Unit,
|
appIcon: @Composable () -> Unit,
|
||||||
|
appTrailing: @Composable () -> Unit,
|
||||||
appVersionsColumn: @Composable ColumnScope.() -> Unit,
|
appVersionsColumn: @Composable ColumnScope.() -> Unit,
|
||||||
appActionsRow: @Composable RowScope.() -> Unit,
|
appActionsRow: @Composable RowScope.() -> Unit,
|
||||||
) {
|
) {
|
||||||
ManagerThemedCard {
|
ManagerTonalCard(
|
||||||
Column {
|
modifier = Modifier.fillMaxWidth(),
|
||||||
ManagerCard {
|
shape = LargeShape,
|
||||||
ManagerListItem(
|
) {
|
||||||
modifier = Modifier.padding(
|
Column(
|
||||||
horizontal = DefaultContentPaddingHorizontal,
|
modifier = Modifier
|
||||||
vertical = DefaultContentPaddingVertical
|
.fillMaxWidth()
|
||||||
),
|
.padding(
|
||||||
title = appTitle,
|
horizontal = DefaultContentPaddingHorizontal,
|
||||||
icon = appIcon
|
vertical = DefaultContentPaddingVertical
|
||||||
)
|
),
|
||||||
}
|
verticalArrangement = Arrangement
|
||||||
CompositionLocalProvider(
|
.spacedBy(DefaultContentPaddingVertical)
|
||||||
LocalContentColor provides MaterialTheme.colors.onSurface
|
) {
|
||||||
|
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
|
||||||
) {
|
) {
|
||||||
Row(
|
Column(
|
||||||
modifier = Modifier.padding(
|
modifier = Modifier.wrapContentWidth(),
|
||||||
horizontal = DefaultContentPaddingHorizontal,
|
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||||
vertical = 8.dp
|
horizontalAlignment = Alignment.Start
|
||||||
),
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
) {
|
) {
|
||||||
Column(
|
ManagerText(
|
||||||
modifier = Modifier
|
text = stringResource(id = R.string.app_versions),
|
||||||
.weight(1f)
|
textStyle = MaterialTheme.typography.bodyMedium
|
||||||
.wrapContentWidth(Alignment.Start),
|
|
||||||
verticalArrangement = Arrangement.spacedBy(4.dp)
|
|
||||||
) {
|
|
||||||
ManagerText(stringResource(id = R.string.app_versions))
|
|
||||||
appVersionsColumn()
|
|
||||||
}
|
|
||||||
Row(
|
|
||||||
modifier = Modifier
|
|
||||||
.weight(1f)
|
|
||||||
.padding(start = 4.dp)
|
|
||||||
.wrapContentWidth(Alignment.End),
|
|
||||||
content = appActionsRow
|
|
||||||
)
|
)
|
||||||
|
appVersionsColumn()
|
||||||
}
|
}
|
||||||
|
Row(
|
||||||
|
modifier = Modifier.wrapContentWidth(),
|
||||||
|
content = appActionsRow,
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.End
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package com.vanced.manager.ui.widget.checkbox
|
||||||
|
|
||||||
import androidx.compose.animation.core.updateTransition
|
import androidx.compose.animation.core.updateTransition
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.material.MaterialTheme
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
@ -10,12 +9,13 @@ import androidx.compose.ui.graphics.Shape
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
import com.vanced.manager.ui.component.animation.jumpAnimation
|
import com.vanced.manager.ui.component.animation.jumpAnimation
|
||||||
import com.vanced.manager.ui.component.checkbox.ManagerCheckbox
|
import com.vanced.manager.ui.component.checkbox.ManagerCheckbox
|
||||||
|
import com.vanced.manager.ui.theme.MediumShape
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ManagerAnimatedCheckbox(
|
fun ManagerAnimatedCheckbox(
|
||||||
size: Dp,
|
size: Dp,
|
||||||
isChecked: Boolean,
|
isChecked: Boolean,
|
||||||
shape: Shape = MaterialTheme.shapes.medium,
|
shape: Shape = MediumShape,
|
||||||
onCheckedChange: (isChecked: Boolean) -> Unit,
|
onCheckedChange: (isChecked: Boolean) -> Unit,
|
||||||
) {
|
) {
|
||||||
val transition = updateTransition(
|
val transition = updateTransition(
|
||||||
|
|
|
@ -1,29 +1,73 @@
|
||||||
package com.vanced.manager.ui.widget.layout
|
package com.vanced.manager.ui.widget.layout
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
|
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.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.Dp
|
import com.vanced.manager.ui.component.color.managerAnimatedColor
|
||||||
import com.vanced.manager.ui.component.text.CategoryTitleText
|
import com.vanced.manager.ui.component.text.ManagerText
|
||||||
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
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun CategoryLayout(
|
fun CategoryLayout(
|
||||||
categoryName: String,
|
categoryName: String,
|
||||||
contentPaddingHorizontal: Dp = DefaultContentPaddingHorizontal,
|
modifier: Modifier = Modifier,
|
||||||
categoryNameSpacing: Dp = DefaultContentPaddingVertical,
|
content: @Composable ColumnScope.() -> Unit,
|
||||||
content: @Composable () -> Unit,
|
|
||||||
) {
|
) {
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = modifier,
|
||||||
verticalArrangement = Arrangement.spacedBy(categoryNameSpacing),
|
verticalArrangement = Arrangement.spacedBy(DefaultContentPaddingVertical)
|
||||||
) {
|
) {
|
||||||
CategoryTitleText(text = categoryName)
|
ManagerText(
|
||||||
Box(
|
modifier = Modifier.padding(start = DefaultContentPaddingHorizontal),
|
||||||
modifier = Modifier.padding(horizontal = contentPaddingHorizontal)
|
text = categoryName,
|
||||||
) {
|
textStyle = MaterialTheme.typography.headlineSmall,
|
||||||
content()
|
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)
|
||||||
|
}
|
||||||
|
|
|
@ -11,8 +11,6 @@ fun SettingsCategoryLayout(
|
||||||
) {
|
) {
|
||||||
CategoryLayout(
|
CategoryLayout(
|
||||||
categoryName = categoryName,
|
categoryName = categoryName,
|
||||||
contentPaddingHorizontal = 0.dp,
|
|
||||||
categoryNameSpacing = 4.dp
|
|
||||||
) {
|
) {
|
||||||
Column {
|
Column {
|
||||||
content()
|
content()
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.vanced.manager.ui.widget.list
|
package com.vanced.manager.ui.widget.list
|
||||||
|
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
import androidx.compose.material.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
package com.vanced.manager.ui.widget.list
|
package com.vanced.manager.ui.widget.list
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
import androidx.compose.material.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
|
@ -2,7 +2,6 @@ package com.vanced.manager.ui.widget.radiobutton
|
||||||
|
|
||||||
import androidx.compose.animation.core.updateTransition
|
import androidx.compose.animation.core.updateTransition
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.material.MaterialTheme
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
@ -10,12 +9,13 @@ import androidx.compose.ui.graphics.Shape
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
import com.vanced.manager.ui.component.animation.jumpAnimation
|
import com.vanced.manager.ui.component.animation.jumpAnimation
|
||||||
import com.vanced.manager.ui.component.radiobutton.ManagerRadiobutton
|
import com.vanced.manager.ui.component.radiobutton.ManagerRadiobutton
|
||||||
|
import com.vanced.manager.ui.theme.MediumShape
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ManagerAnimatedRadiobutton(
|
fun ManagerAnimatedRadiobutton(
|
||||||
size: Dp,
|
size: Dp,
|
||||||
isSelected: Boolean,
|
isSelected: Boolean,
|
||||||
shape: Shape = MaterialTheme.shapes.medium,
|
shape: Shape = MediumShape,
|
||||||
onClick: () -> Unit
|
onClick: () -> Unit
|
||||||
) {
|
) {
|
||||||
val transition = updateTransition(
|
val transition = updateTransition(
|
||||||
|
|
|
@ -13,29 +13,29 @@ import com.vanced.manager.ui.widget.button.ManagerSaveButton
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SettingsAccentColorItem() {
|
fun SettingsAccentColorItem() {
|
||||||
var localAccentColor by remember { mutableStateOf(managerAccentColorPref.value.value) }
|
// var localAccentColor by remember { mutableStateOf(managerAccentColorPref.value.value) }
|
||||||
DialogPreference(
|
// DialogPreference(
|
||||||
preferenceTitle = managerString(
|
// preferenceTitle = managerString(
|
||||||
stringId = R.string.settings_preference_accent_color_title
|
// stringId = R.string.settings_preference_accent_color_title
|
||||||
),
|
// ),
|
||||||
preferenceDescription = "#" + Integer.toHexString(localAccentColor.toInt()),
|
// preferenceDescription = "#" + Integer.toHexString(localAccentColor.toInt()),
|
||||||
buttons = { isShown ->
|
// buttons = { isShown ->
|
||||||
ManagerResetButton(
|
// ManagerResetButton(
|
||||||
backgroundColor = Color(localAccentColor)
|
// backgroundColor = Color(localAccentColor)
|
||||||
) {
|
// ) {
|
||||||
isShown.value = false
|
// isShown.value = false
|
||||||
managerAccentColorPref.save(defAccentColor)
|
// managerAccentColorPref.save(defAccentColor)
|
||||||
}
|
// }
|
||||||
ManagerSaveButton(
|
// ManagerSaveButton(
|
||||||
backgroundColor = Color(localAccentColor)
|
// backgroundColor = Color(localAccentColor)
|
||||||
) {
|
// ) {
|
||||||
isShown.value = false
|
// isShown.value = false
|
||||||
managerAccentColorPref.save(localAccentColor)
|
// managerAccentColorPref.save(localAccentColor)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
) {
|
// ) {
|
||||||
ManagerColorPicker {
|
// ManagerColorPicker {
|
||||||
localAccentColor = it
|
// localAccentColor = it
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
Loading…
Reference in New Issue