Allow changing (preferred) repo in app details

This commit is contained in:
Torsten Grote
2025-10-21 12:08:21 -03:00
parent 4b8ff9678f
commit 2be99156af
6 changed files with 39 additions and 11 deletions

View File

@@ -160,8 +160,8 @@ fun AppDetailsHeader(
repos = item.repositories,
currentRepoId = item.app.repoId,
preferredRepoId = item.preferredRepoId,
onRepoChanged = {},
onPreferredRepoChanged = {},
onRepoChanged = item.actions.onRepoChanged,
onPreferredRepoChanged = item.actions.onPreferredRepoChanged,
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp),
)
// check user confirmation ON_RESUME to work around Android bug

View File

@@ -199,6 +199,8 @@ class AppDetailsActions(
val checkUserConfirmation: (String, InstallState.UserConfirmationNeeded) -> Unit,
val cancelInstall: (String) -> Unit,
val onUninstallResult: (String, ActivityResult) -> Unit,
val onRepoChanged: (Long) -> Unit,
val onPreferredRepoChanged: (Long) -> Unit,
val allowBetaVersions: () -> Unit,
val ignoreAllUpdates: (() -> Unit)? = null,
val ignoreThisUpdate: (() -> Unit)? = null,

View File

@@ -17,6 +17,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import mu.KotlinLogging
@@ -44,6 +45,7 @@ class AppDetailsViewModel @Inject constructor(
) : AndroidViewModel(app) {
private val log = KotlinLogging.logger { }
private val packageInfoFlow = MutableStateFlow<AppInfo?>(null)
private val currentRepoIdFlow = MutableStateFlow<Long?>(null)
val appDetails: StateFlow<AppDetailsItem?> = viewModelScope.launchMolecule(
context = Dispatchers.IO, mode = Immediate,
@@ -55,6 +57,7 @@ class AppDetailsViewModel @Inject constructor(
appInstallManager = appInstallManager,
viewModel = this,
packageInfoFlow = packageInfoFlow,
currentRepoIdFlow = currentRepoIdFlow,
)
}
@@ -136,6 +139,17 @@ class AppDetailsViewModel @Inject constructor(
}
}
@UiThread
fun onRepoChanged(repoId: Long) {
currentRepoIdFlow.update { repoId }
}
@UiThread
fun onPreferredRepoChanged(repoId: Long) {
val packageName = packageInfoFlow.value?.packageName ?: error("Had not package name")
repoManager.setPreferredRepoId(packageName, repoId)
}
override fun onCleared() {
val packageName = packageInfoFlow.value?.packageName
log.info { "App details screen left: $packageName" }

View File

@@ -31,15 +31,17 @@ fun DetailsPresenter(
appInstallManager: AppInstallManager,
viewModel: AppDetailsViewModel,
packageInfoFlow: StateFlow<AppInfo?>,
currentRepoIdFlow: StateFlow<Long?>,
): AppDetailsItem? {
val packagePair = packageInfoFlow.collectAsState().value ?: return null
val packageName = packagePair.packageName
val app = db.getAppDao().getApp(packageName).asFlow().collectAsState(null).value
?: return null
val currentRepoId = currentRepoIdFlow.collectAsState().value
val app = if (currentRepoId == null) {
db.getAppDao().getApp(packageName).asFlow().collectAsState(null).value
} else {
db.getAppDao().getApp(currentRepoId, packageName)
} ?: return null
val repo = repoManager.getRepository(app.repoId) ?: return null
val preferredRepoId = remember(packageName) {
app.repoId // DB loads preferred repo first, so we remember it
}
val repositories = remember(packageName) {
db.getAppDao().getRepositoryIdsForApp(packageName).mapNotNull { repoId ->
repoManager.getRepository(repoId)
@@ -48,9 +50,15 @@ fun DetailsPresenter(
val installState =
appInstallManager.getAppFlow(packageName).collectAsState(InstallState.Unknown).value
val versions =
db.getVersionDao().getAppVersions(packageName).asFlow().collectAsState(null).value
val versions = if (currentRepoId == null) {
db.getVersionDao().getAppVersions(packageName)
} else {
db.getVersionDao().getAppVersions(currentRepoId, packageName)
}.asFlow().collectAsState(null).value
val appPrefs = db.getAppPrefsDao().getAppPrefs(packageName).asFlow().collectAsState(null).value
val preferredRepoId = remember(packageName, appPrefs) {
appPrefs?.preferredRepoId ?: app.repoId // DB loads preferred repo first, so we remember it
}
val suggestedVersion = if (versions == null || appPrefs == null) {
null
} else {
@@ -109,6 +117,8 @@ fun DetailsPresenter(
checkUserConfirmation = viewModel::checkUserConfirmation,
cancelInstall = viewModel::cancelInstall,
onUninstallResult = viewModel::onUninstallResult,
onRepoChanged = viewModel::onRepoChanged,
onPreferredRepoChanged = viewModel::onPreferredRepoChanged,
allowBetaVersions = viewModel::allowBetaUpdates,
ignoreAllUpdates = if (installedVersionCode == null) {
null

View File

@@ -43,7 +43,7 @@ fun RepoChooser(
repos: List<Repository>,
currentRepoId: Long,
preferredRepoId: Long,
onRepoChanged: (Repository) -> Unit,
onRepoChanged: (Long) -> Unit,
onPreferredRepoChanged: (Long) -> Unit,
modifier: Modifier = Modifier,
) {
@@ -116,7 +116,7 @@ fun RepoChooser(
repo = repo,
isPreferred = repo.repoId == preferredRepoId,
onClick = {
onRepoChanged(repo)
onRepoChanged(repo.repoId)
expanded = false
},
modifier = modifier,

View File

@@ -132,6 +132,8 @@ val testApp = AppDetailsItem(
checkUserConfirmation = { _, _ -> },
cancelInstall = {},
onUninstallResult = { _, _ -> },
onRepoChanged = {},
onPreferredRepoChanged = {},
allowBetaVersions = {},
ignoreAllUpdates = {},
ignoreThisUpdate = {},