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