Skip to content

Commit

Permalink
feat: show installed app in version selector
Browse files Browse the repository at this point in the history
  • Loading branch information
CnC-Robert committed Jul 30, 2023
1 parent aec8cec commit 61de0b6
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 58 deletions.
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
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
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
Expand All @@ -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
Expand Down Expand Up @@ -56,6 +61,8 @@ fun VersionSelectorScreen(
}
}

var selectedVersion: SelectedApp? by rememberSaveable { mutableStateOf(null) }

Scaffold(
topBar = {
AppTopBar(
Expand All @@ -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)
)
}
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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()
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@
<string name="loading">Loading…</string>
<string name="not_installed">Not installed</string>

<string name="error_occurred">An error occurred</string>
<string name="already_downloaded">Already downloaded</string>

<string name="select_file">Select file</string>
Expand Down

0 comments on commit 61de0b6

Please sign in to comment.