feat: app info screen

This commit is contained in:
Ushie 2022-12-18 03:54:59 +03:00
parent a161467457
commit accc6ad4c5
No known key found for this signature in database
GPG Key ID: 0EF73F1CA38B2D5F
6 changed files with 254 additions and 8 deletions

View File

@ -21,6 +21,7 @@ import app.revanced.manager.ui.screen.SettingsScreen
import app.revanced.manager.ui.screen.subscreens.* import app.revanced.manager.ui.screen.subscreens.*
import app.revanced.manager.ui.theme.ReVancedManagerTheme import app.revanced.manager.ui.theme.ReVancedManagerTheme
import app.revanced.manager.ui.theme.Theme import app.revanced.manager.ui.theme.Theme
import app.revanced.manager.ui.viewmodel.PatchedApp
import dev.olshevski.navigation.reimagined.* import dev.olshevski.navigation.reimagined.*
import io.sentry.SentryOptions import io.sentry.SentryOptions
import io.sentry.android.core.SentryAndroid import io.sentry.android.core.SentryAndroid
@ -73,7 +74,9 @@ class MainActivity : ComponentActivity() {
onNavChanged = { navController.replaceLast(it) } onNavChanged = { navController.replaceLast(it) }
) { ) {
when (destination) { when (destination) {
AppDestination.Dashboard -> DashboardScreen() AppDestination.Dashboard -> DashboardScreen(
onClickAppInfo = { PatchedApp -> navController.navigate(AppDestination.AppInfo(PatchedApp)) }
)
AppDestination.Patcher -> PatcherScreen( AppDestination.Patcher -> PatcherScreen(
onClickAppSelector = { navController.navigate(AppDestination.AppSelector) }, onClickAppSelector = { navController.navigate(AppDestination.AppSelector) },
onClickPatchSelector = { navController.navigate(AppDestination.PatchSelector) }, onClickPatchSelector = { navController.navigate(AppDestination.PatchSelector) },
@ -86,6 +89,7 @@ class MainActivity : ComponentActivity() {
) )
} }
} }
is AppDestination.AppInfo -> AppInfoSubscreen(onBackClick = { navController.back() }, patchedApp = destination.patchedApp)
is AppDestination.AppSelector -> AppSelectorSubscreen(onBackClick = { navController.back() }) is AppDestination.AppSelector -> AppSelectorSubscreen(onBackClick = { navController.back() })
is AppDestination.PatchSelector -> PatchesSelectorSubscreen(onBackClick = { navController.back() }) is AppDestination.PatchSelector -> PatchesSelectorSubscreen(onBackClick = { navController.back() })
is AppDestination.Contributors -> ContributorsSubscreen(onBackClick = { navController.back() }) is AppDestination.Contributors -> ContributorsSubscreen(onBackClick = { navController.back() })

View File

@ -12,6 +12,7 @@ import androidx.compose.material.icons.outlined.Dashboard
import androidx.compose.material.icons.outlined.Settings import androidx.compose.material.icons.outlined.Settings
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import app.revanced.manager.R import app.revanced.manager.R
import app.revanced.manager.ui.viewmodel.PatchedApp
import dev.olshevski.navigation.reimagined.NavController import dev.olshevski.navigation.reimagined.NavController
import dev.olshevski.navigation.reimagined.pop import dev.olshevski.navigation.reimagined.pop
import dev.olshevski.navigation.reimagined.replaceAll import dev.olshevski.navigation.reimagined.replaceAll
@ -45,6 +46,9 @@ sealed interface AppDestination : Parcelable {
@Parcelize @Parcelize
object Patching : AppDestination object Patching : AppDestination
@Parcelize
class AppInfo(val patchedApp: PatchedApp) : AppDestination
@Parcelize @Parcelize
object SourceSelector : AppDestination object SourceSelector : AppDestination

View File

@ -16,14 +16,19 @@ import androidx.compose.ui.unit.dp
import app.revanced.manager.R import app.revanced.manager.R
import app.revanced.manager.ui.component.AppIcon import app.revanced.manager.ui.component.AppIcon
import app.revanced.manager.ui.component.ApplicationItem import app.revanced.manager.ui.component.ApplicationItem
import app.revanced.manager.ui.component.ApplicationItemDualTint
import app.revanced.manager.ui.component.HeadlineWithCard import app.revanced.manager.ui.component.HeadlineWithCard
import app.revanced.manager.ui.viewmodel.DashboardViewModel import app.revanced.manager.ui.viewmodel.DashboardViewModel
import app.revanced.manager.ui.viewmodel.PatchedApp
import app.revanced.manager.util.loadIcon import app.revanced.manager.util.loadIcon
import org.koin.androidx.compose.getViewModel import org.koin.androidx.compose.getViewModel
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun DashboardScreen(viewModel: DashboardViewModel = getViewModel()) { fun DashboardScreen(
viewModel: DashboardViewModel = getViewModel(),
onClickAppInfo: (PatchedApp) -> Unit
) {
var showUpdates by remember { mutableStateOf(false) } var showUpdates by remember { mutableStateOf(false) }
val context = LocalContext.current val context = LocalContext.current
val padHoriz = 16.dp val padHoriz = 16.dp
@ -87,7 +92,7 @@ fun DashboardScreen(viewModel: DashboardViewModel = getViewModel()) {
verticalArrangement = Arrangement.spacedBy(12.dp) verticalArrangement = Arrangement.spacedBy(12.dp)
) { ) {
viewModel.apps.forEach { viewModel.apps.forEach {
ApplicationItem( ApplicationItemDualTint(
appName = it.appName, appName = it.appName,
appIcon = { appIcon = {
AppIcon( AppIcon(
@ -96,9 +101,10 @@ fun DashboardScreen(viewModel: DashboardViewModel = getViewModel()) {
size = 38 size = 38
) )
}, },
releaseAgo = it.version appVersion = it.appVersion,
) { onClick = { onClickAppInfo(it) },
} expandedContent = { Text("CANNNNNNNNNNNNNNNNNNNNNNNNNNNNNY") }
)
} }
} }
} }

View File

@ -0,0 +1,226 @@
package app.revanced.manager.ui.screen.subscreens
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Build
import androidx.compose.material.icons.outlined.Delete
import androidx.compose.material.icons.outlined.Launch
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import app.revanced.manager.R
import app.revanced.manager.ui.component.AppIcon
import app.revanced.manager.ui.component.AppMediumTopBar
import app.revanced.manager.ui.component.AppScaffold
import app.revanced.manager.ui.viewmodel.PatchedApp
import app.revanced.manager.util.loadIcon
import java.time.format.DateTimeFormatter
import java.time.format.FormatStyle
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AppInfoSubscreen(
onBackClick: () -> Unit,
patchedApp: PatchedApp,
) {
val context = LocalContext.current
var showDialog by remember { mutableStateOf(false) }
AppScaffold(
topBar = { scrollBehavior ->
AppMediumTopBar(
topBarTitle = stringResource(R.string.app_info),
scrollBehavior = scrollBehavior,
onBackClick = onBackClick
)
}
) { paddingValues ->
Column(
Modifier
.fillMaxSize()
.verticalScroll(rememberScrollState())
.padding(paddingValues)
) {
if (showDialog) {
AlertDialog(
title = { Text(text = "Applied patches") },
onDismissRequest = { showDialog = false },
confirmButton = {
TextButton(onClick = { showDialog = false }) {
Text(stringResource(R.string.dismiss))
}
},
text = {
LazyColumn {
items(count = patchedApp.appliedPatches.count()) {
Text(text = "\u2022 ${patchedApp.appliedPatches[it]}")
}
}
}
)
}
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(6.dp)
) {
AppIcon(
drawable = context.loadIcon(patchedApp.pkgName),
contentDescription = null,
size = 64
)
Text(
text = patchedApp.appName,
fontSize = 23.sp
)
Text(patchedApp.appVersion)
Box(
modifier = Modifier
.fillMaxWidth()
.height(100.dp)
.padding(16.dp, 16.dp, 16.dp, 0.dp)
.clip(RoundedCornerShape(20.dp))
.background(MaterialTheme.colorScheme.surfaceColorAtElevation(1.dp))
) {
Row(
verticalAlignment = Alignment.CenterVertically
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
modifier = Modifier
.weight(1f)
.clickable { }
.fillMaxSize()
) {
Icon(
imageVector = Icons.Outlined.Launch,
contentDescription = null,
tint = MaterialTheme.colorScheme.primary
)
Text(
text = "Launch",
color = MaterialTheme.colorScheme.primary,
fontSize = 16.sp,
fontWeight = FontWeight.Bold
)
}
Divider(
modifier = Modifier
.width(.5.dp)
.fillMaxHeight()
.padding(vertical = 16.dp),
color = MaterialTheme.colorScheme.background
)
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
modifier = Modifier
.weight(1f)
.clickable { }
.fillMaxSize()
) {
Icon(
imageVector = Icons.Outlined.Delete,
contentDescription = null,
tint = MaterialTheme.colorScheme.primary
)
Text(
text = "Uninstall",
color = MaterialTheme.colorScheme.primary,
fontSize = 16.sp,
fontWeight = FontWeight.Bold
)
}
Divider(
modifier = Modifier
.width(.5.dp)
.fillMaxHeight()
.padding(vertical = 16.dp),
color = MaterialTheme.colorScheme.background
)
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
modifier = Modifier
.weight(1f)
.clickable { }
.fillMaxSize()
) {
Icon(
imageVector = Icons.Outlined.Build,
contentDescription = null,
tint = MaterialTheme.colorScheme.primary
)
Text(
text = "Patch",
color = MaterialTheme.colorScheme.primary,
fontSize = 16.sp,
fontWeight = FontWeight.Bold
)
}
}
}
ListItem(
headlineText = {
Text(
"Package name",
fontSize = 20.sp,
fontWeight = FontWeight(500)
)
},
supportingText = {
Text(
text = patchedApp.pkgName
)
}
)
ListItem(
headlineText = {
Text(
text = "Patched date",
fontSize = 20.sp,
fontWeight = FontWeight(500)
)
},
supportingText = {
Text(
text = patchedApp.patchedDate
)
}
)
ListItem(
modifier = Modifier.clickable { showDialog = true },
headlineText = {
Text(
text = "Applied patches",
fontSize = 20.sp,
fontWeight = FontWeight(500)
)
},
supportingText = {
Text(
text = if (patchedApp.appliedPatches.count() == 1) {
"1 applied patch"
} else {
"${patchedApp.appliedPatches.count()} applied patches"
}
)
}
)
}
}
}
}

View File

@ -21,6 +21,9 @@ import app.revanced.manager.patcher.PatcherUtils
import app.revanced.manager.patcher.worker.PatcherWorker import app.revanced.manager.patcher.worker.PatcherWorker
import app.revanced.manager.util.appName import app.revanced.manager.util.appName
import java.io.File import java.io.File
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.time.format.FormatStyle
class PatchingScreenViewModel( class PatchingScreenViewModel(
private val app: Application, private val app: Application,
@ -125,8 +128,9 @@ class PatchingScreenViewModel(
PatchedApp( PatchedApp(
appName = app.appName(applicationInfo), appName = app.appName(applicationInfo),
pkgName = applicationInfo.packageName, pkgName = applicationInfo.packageName,
version = versionName, appVersion = versionName,
appliedPatches = patcherUtils.selectedPatches appliedPatches = patcherUtils.selectedPatches,
patchedDate = LocalDateTime.now().format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)).toString()
) )
} }
) )

View File

@ -66,4 +66,6 @@
<string name="failed">Failed!</string> <string name="failed">Failed!</string>
<string name="permissions">Permissions</string> <string name="permissions">Permissions</string>
<string name="permission_request">ReVanced Manager relies on some permissions to function properly, please give required permissions by pressing OK.</string> <string name="permission_request">ReVanced Manager relies on some permissions to function properly, please give required permissions by pressing OK.</string>
<string name="app_info">App info</string>
<string name="info">Info</string>
</resources> </resources>