feat: improved dashboard screen

This commit is contained in:
CnC-Robert 2023-05-18 13:46:59 +02:00
parent 4c3dbbd8d5
commit f1656c6d1e
2 changed files with 87 additions and 78 deletions

View File

@ -20,7 +20,6 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import app.revanced.manager.compose.R import app.revanced.manager.compose.R
import app.revanced.manager.compose.ui.component.AppIcon import app.revanced.manager.compose.ui.component.AppIcon
import app.revanced.manager.compose.ui.component.AppScaffold
import app.revanced.manager.compose.ui.component.AppTopBar import app.revanced.manager.compose.ui.component.AppTopBar
import app.revanced.manager.compose.ui.component.LoadingIndicator import app.revanced.manager.compose.ui.component.LoadingIndicator
import app.revanced.manager.compose.util.PM import app.revanced.manager.compose.util.PM
@ -28,6 +27,7 @@ import app.revanced.manager.compose.util.PM
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun AppSelectorScreen( fun AppSelectorScreen(
onAppClick: () -> Unit,
onBackClick: () -> Unit onBackClick: () -> Unit
) { ) {
var filterText by rememberSaveable { mutableStateOf("") } var filterText by rememberSaveable { mutableStateOf("") }
@ -43,7 +43,7 @@ fun AppSelectorScreen(
onActiveChange = { search = it }, onActiveChange = { search = it },
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
placeholder = { Text(stringResource(R.string.search_apps)) }, placeholder = { Text(stringResource(R.string.search_apps)) },
leadingIcon = { IconButton({ search = false }) { Icon(Icons.Default.ArrowBack, null) } }, leadingIcon = { IconButton({ search = false }) { Icon(Icons.Default.ArrowBack, stringResource(R.string.back)) } },
shape = SearchBarDefaults.inputFieldShape, shape = SearchBarDefaults.inputFieldShape,
content = { content = {
if (PM.appList.isNotEmpty()) { if (PM.appList.isNotEmpty()) {
@ -61,11 +61,11 @@ fun AppSelectorScreen(
) { app -> ) { app ->
ListItem( ListItem(
modifier = Modifier.clickable { }, modifier = Modifier.clickable { onAppClick() },
leadingContent = { AppIcon(app.icon, null, 36) }, leadingContent = { AppIcon(app.icon, null, 36) },
headlineContent = { Text(app.label) }, headlineContent = { Text(app.label) },
supportingContent = { Text(app.packageName) }, supportingContent = { Text(app.packageName) },
trailingContent = { Text((PM.testList[app.packageName]?: 0).let { if (it == 1) "$it Patch" else "$it Patches" }) } trailingContent = { Text((PM.testList[app.packageName]?: 0).let { if (it == 1) "$it " + stringResource(R.string.patch) else "$it " + stringResource(R.string.patches) }) }
) )
} }
@ -77,17 +77,17 @@ fun AppSelectorScreen(
) )
} }
AppScaffold( Scaffold(
topBar = { topBar = {
AppTopBar( AppTopBar(
title = "Select an app", title = stringResource(R.string.select_app),
onBackClick = onBackClick, onBackClick = onBackClick,
actions = { actions = {
IconButton({}) { IconButton(onClick = { }) {
Icon(Icons.Outlined.HelpOutline, "Help") Icon(Icons.Outlined.HelpOutline, stringResource(R.string.help))
} }
IconButton(onClick = { search = true }) { IconButton(onClick = { search = true }) {
Icon(Icons.Outlined.Search, "Search") Icon(Icons.Outlined.Search, stringResource(R.string.search))
} }
} }
) )
@ -100,6 +100,62 @@ fun AppSelectorScreen(
) { ) {
if (PM.supportedAppList.isNotEmpty()) { if (PM.supportedAppList.isNotEmpty()) {
LazyColumn(
modifier = Modifier.fillMaxSize()
) {
item {
ListItem(
modifier = Modifier.clickable { },
leadingContent = { Box(Modifier.size(36.dp), Alignment.Center) { Icon(Icons.Default.Storage, null, modifier = Modifier.size(24.dp)) } },
headlineContent = { Text(stringResource(R.string.select_from_storage)) }
)
Divider()
}
(PM.appList.ifEmpty { PM.supportedAppList }).also { list ->
items(
count = list.size,
key = { list[it].packageName }
) { index ->
val app = list[index]
ListItem(
modifier = Modifier.clickable { onAppClick() },
leadingContent = { AppIcon(app.icon, null, 36) },
headlineContent = { Text(app.label) },
supportingContent = { Text(app.packageName) },
trailingContent = {
Text(
(PM.testList[app.packageName]?: 0).let { if (it == 1) "$it " + stringResource(R.string.patch) else "$it " + stringResource(R.string.patches) }
)
}
)
}
if (PM.appList.isEmpty()) {
item {
Box(Modifier.fillMaxWidth(), Alignment.Center) {
CircularProgressIndicator(Modifier.padding(vertical = 15.dp).size(24.dp), strokeWidth = 3.dp)
}
}
}
}
}
} else {
LoadingIndicator()
}
}
}
}
/*Row( /*Row(
modifier = Modifier.horizontalScroll(rememberScrollState()), modifier = Modifier.horizontalScroll(rememberScrollState()),
horizontalArrangement = Arrangement.spacedBy(10.dp) horizontalArrangement = Arrangement.spacedBy(10.dp)
@ -124,55 +180,3 @@ fun AppSelectorScreen(
leadingIcon = { Icon(Icons.Default.Apps, null) } leadingIcon = { Icon(Icons.Default.Apps, null) }
) )
}*/ }*/
LazyColumn(
modifier = Modifier.fillMaxSize()
) {
item {
ListItem(
modifier = Modifier.clickable { },
leadingContent = { Box(Modifier.size(36.dp), Alignment.Center) { Icon(Icons.Default.Storage, null, modifier = Modifier.size(24.dp)) } },
headlineContent = { Text("Select from storage") }
)
Divider()
}
(PM.appList.ifEmpty { PM.supportedAppList }).also { list ->
items(
count = list.size,
key = { list[it].packageName }
) { index ->
val app = list[index]
ListItem(
modifier = Modifier.clickable { },
leadingContent = { AppIcon(app.icon, null, 36) },
headlineContent = { Text(app.label) },
supportingContent = { Text(app.packageName) },
trailingContent = {
Text(
(PM.testList[app.packageName]?: 0).let { if (it == 1) "$it Patch" else "$it Patches" }
)
}
)
}
if (PM.appList.isEmpty()) {
item {
Box(Modifier.fillMaxWidth(), Alignment.Center) {
CircularProgressIndicator(Modifier.padding(vertical = 15.dp).size(24.dp), strokeWidth = 3.dp)
}
}
}
}
}
} else {
LoadingIndicator()
}
}
}
}

View File

@ -7,14 +7,21 @@ import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.Android
import androidx.compose.material.icons.outlined.Apps
import androidx.compose.material.icons.outlined.HelpOutline
import androidx.compose.material.icons.outlined.Info import androidx.compose.material.icons.outlined.Info
import androidx.compose.material.icons.outlined.Notifications import androidx.compose.material.icons.outlined.Notifications
import androidx.compose.material.icons.outlined.Settings import androidx.compose.material.icons.outlined.Settings
import androidx.compose.material.icons.outlined.Source
import androidx.compose.material.icons.outlined.Topic
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.LeadingIconTab
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Tab import androidx.compose.material3.Tab
import androidx.compose.material3.TabRow import androidx.compose.material3.TabRow
import androidx.compose.material3.Text import androidx.compose.material3.Text
@ -22,6 +29,7 @@ import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import app.revanced.manager.compose.R import app.revanced.manager.compose.R
@ -31,35 +39,33 @@ import kotlinx.coroutines.launch
enum class DashboardPage( enum class DashboardPage(
val titleResId: Int, val titleResId: Int,
val icon: ImageVector
) { ) {
DASHBOARD(R.string.tab_apps), DASHBOARD(R.string.tab_apps, Icons.Outlined.Apps),
SOURCES(R.string.tab_sources), SOURCES(R.string.tab_sources, Icons.Outlined.Source),
} }
@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterial3Api::class) @OptIn(ExperimentalFoundationApi::class, ExperimentalMaterial3Api::class)
@Composable @Composable
fun DashboardScreen( fun DashboardScreen(
onAppSelectorClick: () -> Unit onAppSelectorClick: () -> Unit,
onSettingsClick: () -> Unit
) { ) {
val pages: Array<DashboardPage> = DashboardPage.values() val pages: Array<DashboardPage> = DashboardPage.values()
val pagerState = rememberPagerState() val pagerState = rememberPagerState()
val coroutineScope = rememberCoroutineScope() val coroutineScope = rememberCoroutineScope()
AppScaffold( Scaffold(
topBar = { topBar = {
AppTopBar( AppTopBar(
title = "ReVanced Manager", title = stringResource(R.string.app_name),
actions = { actions = {
IconButton(onClick = {}) { IconButton(onClick = {}) {
Icon(imageVector = Icons.Outlined.Info, contentDescription = null) Icon(Icons.Outlined.HelpOutline, stringResource(R.string.help))
} }
IconButton(onClick = {}) { IconButton(onClick = onSettingsClick) {
Icon(imageVector = Icons.Outlined.Notifications, contentDescription = null) Icon(Icons.Outlined.Settings, stringResource(R.string.settings))
}
IconButton(onClick = {}) {
Icon(imageVector = Icons.Outlined.Settings, contentDescription = null)
} }
} }
) )
@ -70,7 +76,7 @@ fun DashboardScreen(
onAppSelectorClick() onAppSelectorClick()
} }
) { ) {
Icon(imageVector = Icons.Default.Add, contentDescription = null) Icon(Icons.Default.Add, stringResource(R.string.add))
} }
} }
) { paddingValues -> ) { paddingValues ->
@ -80,13 +86,13 @@ fun DashboardScreen(
containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(3.0.dp) containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(3.0.dp)
) { ) {
pages.forEachIndexed { index, page -> pages.forEachIndexed { index, page ->
val title = stringResource(id = page.titleResId)
Tab( Tab(
selected = pagerState.currentPage == index, selected = pagerState.currentPage == index,
onClick = { coroutineScope.launch { pagerState.animateScrollToPage(index) } }, onClick = { coroutineScope.launch { pagerState.animateScrollToPage(index) } },
text = { Text(text = title) }, text = { Text(stringResource(page.titleResId)) },
icon = { Icon(page.icon, null) },
selectedContentColor = MaterialTheme.colorScheme.primary, selectedContentColor = MaterialTheme.colorScheme.primary,
unselectedContentColor = MaterialTheme.colorScheme.onSurface, unselectedContentColor = MaterialTheme.colorScheme.onSurfaceVariant
) )
} }
} }
@ -95,7 +101,6 @@ fun DashboardScreen(
pageCount = pages.size, pageCount = pages.size,
state = pagerState, state = pagerState,
userScrollEnabled = true, userScrollEnabled = true,
contentPadding = paddingValues,
pageContent = { index -> pageContent = { index ->
when (pages[index]) { when (pages[index]) {
DashboardPage.DASHBOARD -> { DashboardPage.DASHBOARD -> {