diff --git a/app/src/main/java/app/revanced/manager/ui/screen/VersionSelectorScreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/VersionSelectorScreen.kt
index b35d750b8e..f2b8169abb 100644
--- a/app/src/main/java/app/revanced/manager/ui/screen/VersionSelectorScreen.kt
+++ b/app/src/main/java/app/revanced/manager/ui/screen/VersionSelectorScreen.kt
@@ -1,7 +1,6 @@
package app.revanced.manager.ui.screen
import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
@@ -9,18 +8,23 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Check
import androidx.compose.material.icons.outlined.HelpOutline
-import androidx.compose.material.icons.outlined.Search
import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.ListItem
+import androidx.compose.material3.RadioButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
+import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.pluralStringResource
@@ -29,6 +33,7 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import app.revanced.manager.R
import app.revanced.manager.ui.component.AppTopBar
+import app.revanced.manager.ui.component.GroupHeader
import app.revanced.manager.ui.component.LoadingIndicator
import app.revanced.manager.ui.model.SelectedApp
import app.revanced.manager.ui.viewmodel.VersionSelectorViewModel
@@ -56,6 +61,8 @@ fun VersionSelectorScreen(
}
}
+ var selectedVersion: SelectedApp? by rememberSaveable { mutableStateOf(null) }
+
Scaffold(
topBar = {
AppTopBar(
@@ -65,75 +72,95 @@ fun VersionSelectorScreen(
IconButton(onClick = { }) {
Icon(Icons.Outlined.HelpOutline, stringResource(R.string.help))
}
- IconButton(onClick = { }) {
- Icon(Icons.Outlined.Search, stringResource(R.string.search))
- }
}
)
+ },
+ floatingActionButton = {
+ ExtendedFloatingActionButton(
+ text = { Text("Select version") },
+ icon = { Icon(Icons.Default.Check, null) },
+ onClick = { selectedVersion?.let(onAppClick) }
+ )
}
) { paddingValues ->
Column(
modifier = Modifier
.padding(paddingValues)
- .fillMaxSize(),
- verticalArrangement = Arrangement.Center,
- horizontalAlignment = Alignment.CenterHorizontally
+ .fillMaxSize()
+ .verticalScroll(rememberScrollState())
) {
- when {
- !viewModel.isDownloading && list.isNotEmpty() -> {
- Column(
- modifier = Modifier
- .fillMaxSize()
- .verticalScroll(rememberScrollState())
- ) {
- list.forEach { selectedApp ->
- ListItem(
- modifier = Modifier.clickable { onAppClick(selectedApp) },
- headlineContent = { Text(selectedApp.version) },
- supportingContent =
- if (selectedApp is SelectedApp.Local) {
- { Text(stringResource(R.string.already_downloaded)) }
- } else null,
- trailingContent = supportedVersions[selectedApp.version]?.let { {
- Text(
- pluralStringResource(
- R.plurals.patches_count,
- count = it,
- it
- )
- )
- }
- }
- )
- }
- if (viewModel.errorMessage != null) {
- Column(
- modifier = Modifier.fillMaxWidth(),
- horizontalAlignment = Alignment.CenterHorizontally
- ) {
- Text(stringResource(R.string.error_occurred))
- Text(
- text = viewModel.errorMessage!!,
- modifier = Modifier.padding(horizontal = 15.dp)
- )
- }
- } else if (viewModel.isLoading)
- LoadingIndicator()
- }
+ viewModel.installedApp?.let { packageInfo ->
+ SelectedApp.Installed(
+ packageName = viewModel.packageName,
+ version = packageInfo.versionName
+ ).let {
+ SelectedAppItem(
+ selectedApp = it,
+ selected = selectedVersion == it,
+ onClick = { selectedVersion = it },
+ patchCount = supportedVersions[it.version]
+ )
}
+ }
+
+ GroupHeader("Downloadable versions")
+
+ list.forEach {
+ SelectedAppItem(
+ selectedApp = it,
+ selected = selectedVersion == it,
+ onClick = { selectedVersion = it },
+ patchCount = supportedVersions[it.version]
+ )
+ }
- viewModel.errorMessage != null -> {
+ if (viewModel.errorMessage != null) {
+ Column(
+ modifier = Modifier.fillMaxWidth(),
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
Text(stringResource(R.string.error_occurred))
Text(
text = viewModel.errorMessage!!,
modifier = Modifier.padding(horizontal = 15.dp)
)
}
+ } else if (viewModel.isLoading)
+ LoadingIndicator()
- else -> {
- LoadingIndicator()
- }
- }
}
}
+}
+
+const val alreadyPatched = false
+
+@Composable
+fun SelectedAppItem(
+ selectedApp: SelectedApp,
+ selected: Boolean,
+ onClick: () -> Unit,
+ patchCount: Int?
+) {
+ ListItem(
+ leadingContent = { RadioButton(selected, null) },
+ headlineContent = { Text(selectedApp.version) },
+ supportingContent = when (selectedApp) {
+ is SelectedApp.Installed ->
+ if (alreadyPatched) {
+ { Text("Already patched") }
+ } else {
+ { Text("Installed") }
+ }
+
+ is SelectedApp.Local -> {
+ { Text(stringResource(R.string.already_downloaded)) }
+ }
+
+ else -> null
+ },
+ trailingContent = patchCount?.let { {
+ Text(pluralStringResource(R.plurals.patches_count, it, it))
+ } },
+ modifier = Modifier.clickable(onClick = onClick)
+ )
}
\ No newline at end of file
diff --git a/app/src/main/java/app/revanced/manager/ui/viewmodel/VersionSelectorViewModel.kt b/app/src/main/java/app/revanced/manager/ui/viewmodel/VersionSelectorViewModel.kt
index 044a5c8145..aac27f1196 100644
--- a/app/src/main/java/app/revanced/manager/ui/viewmodel/VersionSelectorViewModel.kt
+++ b/app/src/main/java/app/revanced/manager/ui/viewmodel/VersionSelectorViewModel.kt
@@ -1,5 +1,6 @@
package app.revanced.manager.ui.viewmodel
+import android.content.pm.PackageInfo
import android.util.Log
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@@ -11,6 +12,7 @@ import app.revanced.manager.domain.repository.SourceRepository
import app.revanced.manager.network.downloader.APKMirror
import app.revanced.manager.network.downloader.AppDownloader
import app.revanced.manager.ui.model.SelectedApp
+import app.revanced.manager.util.PM
import app.revanced.manager.util.mutableStateSetOf
import app.revanced.manager.util.simpleMessage
import app.revanced.manager.util.tag
@@ -20,16 +22,17 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.koin.core.component.KoinComponent
-import org.koin.core.component.get
+import org.koin.core.component.inject
class VersionSelectorViewModel(
val packageName: String
) : ViewModel(), KoinComponent {
- private val downloadedAppRepository: DownloadedAppRepository = get()
- private val sourceRepository: SourceRepository = get()
+ private val downloadedAppRepository: DownloadedAppRepository by inject()
+ private val sourceRepository: SourceRepository by inject()
+ private val pm: PM by inject()
private val appDownloader: AppDownloader = APKMirror()
- var isDownloading: Boolean by mutableStateOf(false)
+ var installedApp: PackageInfo? by mutableStateOf(null)
private set
var isLoading by mutableStateOf(true)
private set
@@ -63,6 +66,10 @@ class VersionSelectorViewModel(
}
init {
+ viewModelScope.launch(Dispatchers.Main) {
+ installedApp = withContext(Dispatchers.IO) { pm.getPackageInfo(packageName) }
+ }
+
viewModelScope.launch(Dispatchers.IO) {
try {
val compatibleVersions = supportedVersions.first()
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index d57ca41f52..98dd93ec99 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -131,6 +131,7 @@
Loading…
Not installed
+ An error occurred
Already downloaded
Select file