mirror of
https://github.com/f-droid/fdroidclient.git
synced 2026-05-19 14:10:38 -04:00
Only show one app confirmation dialog at a time
This commit is contained in:
@@ -20,6 +20,7 @@ sealed class InstallState(val showProgress: Boolean) {
|
||||
val version: AppVersion,
|
||||
val repo: Repository,
|
||||
override val sessionId: Int,
|
||||
override val creationTimeMillis: Long = System.currentTimeMillis(),
|
||||
override val intent: PendingIntent,
|
||||
) : InstallConfirmationState() {
|
||||
override val name: String = state.name
|
||||
@@ -67,6 +68,7 @@ sealed class InstallState(val showProgress: Boolean) {
|
||||
override val iconDownloadRequest: DownloadRequest?,
|
||||
override val sessionId: Int,
|
||||
override val intent: PendingIntent,
|
||||
override val creationTimeMillis: Long,
|
||||
val progress: Float,
|
||||
) : InstallConfirmationState() {
|
||||
constructor(
|
||||
@@ -82,6 +84,7 @@ sealed class InstallState(val showProgress: Boolean) {
|
||||
iconDownloadRequest = state.iconDownloadRequest,
|
||||
sessionId = sessionId,
|
||||
intent = intent,
|
||||
creationTimeMillis = System.currentTimeMillis(),
|
||||
progress = progress
|
||||
)
|
||||
}
|
||||
@@ -127,5 +130,14 @@ sealed class InstallStateWithInfo(showProgress: Boolean) : InstallState(showProg
|
||||
|
||||
sealed class InstallConfirmationState() : InstallStateWithInfo(true) {
|
||||
abstract val sessionId: Int
|
||||
|
||||
/**
|
||||
* The epoch time in milliseconds when this state was created.
|
||||
* This is used to get a stable ordering on apps that require user confirmation.
|
||||
* The reason this is needed is that we can only show a single confirmation dialog at a time.
|
||||
* If we show more than one, the second one gets silently swallowed by the system
|
||||
* and we don't receive any feedback, so installation process of several apps gets stuck.
|
||||
*/
|
||||
abstract val creationTimeMillis: Long
|
||||
abstract val intent: PendingIntent
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import androidx.compose.material3.TopAppBarDefaults.enterAlwaysScrollBehavior
|
||||
import androidx.compose.material3.rememberTopAppBarState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
@@ -59,18 +58,11 @@ fun MyApps(
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val myAppsModel = myAppsInfo.model
|
||||
val appToConfirm by remember(myAppsInfo.model.installingApps) {
|
||||
derivedStateOf {
|
||||
myAppsInfo.model.installingApps.find { app ->
|
||||
app.installState is InstallConfirmationState
|
||||
}
|
||||
}
|
||||
}
|
||||
// Ask user to confirm appToConfirm whenever it changes and we are in STARTED state.
|
||||
// In tests, waiting for RESUME didn't work, because the LaunchedEffect ran before.
|
||||
val lifecycleOwner = LocalLifecycleOwner.current
|
||||
LaunchedEffect(appToConfirm) {
|
||||
val app = appToConfirm
|
||||
LaunchedEffect(myAppsModel.appToConfirm) {
|
||||
val app = myAppsModel.appToConfirm
|
||||
if (app != null && lifecycleOwner.lifecycle.currentState.isAtLeast(STARTED)) {
|
||||
val state = app.installState as InstallConfirmationState
|
||||
myAppsInfo.confirmAppInstall(app.packageName, state)
|
||||
|
||||
@@ -14,8 +14,9 @@ interface MyAppsInfo {
|
||||
}
|
||||
|
||||
data class MyAppsModel(
|
||||
val installingApps: List<InstallingAppItem>,
|
||||
val appToConfirm: InstallingAppItem? = null,
|
||||
val appUpdates: List<AppUpdateItem>? = null,
|
||||
val installingApps: List<InstallingAppItem>,
|
||||
val appsWithIssue: List<AppWithIssueItem>? = null,
|
||||
val installedApps: List<InstalledAppItem>? = null,
|
||||
val sortOrder: AppListSortOrder = AppListSortOrder.NAME,
|
||||
|
||||
@@ -8,6 +8,7 @@ import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import org.fdroid.database.AppListSortOrder
|
||||
import org.fdroid.download.NetworkState
|
||||
import org.fdroid.install.InstallConfirmationState
|
||||
import org.fdroid.install.InstallState
|
||||
import org.fdroid.install.InstallStateWithInfo
|
||||
import org.fdroid.ui.utils.normalize
|
||||
@@ -87,6 +88,11 @@ fun MyAppsPresenter(
|
||||
}
|
||||
} ?: run { updateBytes = null }
|
||||
return MyAppsModel(
|
||||
appToConfirm = installingApps.filter {
|
||||
it.installState is InstallConfirmationState
|
||||
}.minByOrNull {
|
||||
(it.installState as InstallConfirmationState).creationTimeMillis
|
||||
},
|
||||
installingApps = installingApps.sort(sortOrder),
|
||||
appUpdates = updates?.sort(sortOrder),
|
||||
appsWithIssue = withIssues?.sort(sortOrder),
|
||||
|
||||
Reference in New Issue
Block a user