diff --git a/composeApp/src/commonMain/kotlin/org/ooni/probe/data/repositories/TestDescriptorRepository.kt b/composeApp/src/commonMain/kotlin/org/ooni/probe/data/repositories/TestDescriptorRepository.kt index e1ebad86..1fd44083 100644 --- a/composeApp/src/commonMain/kotlin/org/ooni/probe/data/repositories/TestDescriptorRepository.kt +++ b/composeApp/src/commonMain/kotlin/org/ooni/probe/data/repositories/TestDescriptorRepository.kt @@ -19,9 +19,9 @@ class TestDescriptorRepository( private val json: Json, private val backgroundContext: CoroutineContext, ) { - fun list() = + fun list(isExpired: Boolean? = null) = database.testDescriptorQueries - .selectAll() + .selectAll(isExpired = isExpired?.let { if (it) 1 else 0 }) .asFlow() .mapToList(backgroundContext) .map { list -> list.mapNotNull { it.toModel() } } diff --git a/composeApp/src/commonMain/kotlin/org/ooni/probe/domain/GetTestDescriptors.kt b/composeApp/src/commonMain/kotlin/org/ooni/probe/domain/GetTestDescriptors.kt index cff89106..b9b77908 100644 --- a/composeApp/src/commonMain/kotlin/org/ooni/probe/domain/GetTestDescriptors.kt +++ b/composeApp/src/commonMain/kotlin/org/ooni/probe/domain/GetTestDescriptors.kt @@ -19,13 +19,13 @@ import org.ooni.probe.data.models.toDescriptor class GetTestDescriptors( private val getDefaultTestDescriptors: () -> List, - private val listInstalledTestDescriptors: () -> Flow>, + private val listInstalledTestDescriptors: (Boolean?) -> Flow>, private val descriptorUpdates: () -> Flow, private val getPreferenceValues: (List) -> Flow>, ) { - operator fun invoke(): Flow> { + operator fun invoke(isExpired: Boolean? = null): Flow> { return combine( - listInstalledTestDescriptors(), + listInstalledTestDescriptors(isExpired), descriptorUpdates(), flowOf(getDefaultTestDescriptors()), isWebsitesDescriptorEnabled(), diff --git a/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/dashboard/TestDescriptorItem.kt b/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/dashboard/TestDescriptorItem.kt index 71754138..389a9297 100644 --- a/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/dashboard/TestDescriptorItem.kt +++ b/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/dashboard/TestDescriptorItem.kt @@ -19,6 +19,7 @@ import ooniprobe.composeapp.generated.resources.Res import ooniprobe.composeapp.generated.resources.ic_chevron_right import org.jetbrains.compose.resources.painterResource import org.ooni.probe.data.models.Descriptor +import org.ooni.probe.ui.shared.ExpiredChip import org.ooni.probe.ui.shared.UpdatesChip @Composable @@ -56,6 +57,9 @@ fun TestDescriptorItem( if (descriptor.updatable) { UpdatesChip(onClick = updateDescriptor) } + if (descriptor.isExpired) { + ExpiredChip() + } Icon( painter = painterResource(Res.drawable.ic_chevron_right), contentDescription = null, diff --git a/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/descriptor/DescriptorScreen.kt b/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/descriptor/DescriptorScreen.kt index 2e214413..286d46d6 100644 --- a/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/descriptor/DescriptorScreen.kt +++ b/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/descriptor/DescriptorScreen.kt @@ -54,6 +54,7 @@ import org.ooni.probe.config.OrganizationConfig import org.ooni.probe.config.TestDisplayMode import org.ooni.probe.data.models.Descriptor import org.ooni.probe.data.models.NetTest +import org.ooni.probe.ui.shared.ExpiredChip import org.ooni.probe.ui.shared.MarkdownViewer import org.ooni.probe.ui.shared.SelectableItem import org.ooni.probe.ui.shared.TopBar @@ -263,6 +264,11 @@ private fun DescriptorDetails( if (descriptor.updatable) { UpdatesChip(onClick = { }, modifier = Modifier.padding(top = 8.dp)) } + + if (descriptor.isExpired) { + ExpiredChip() + } + state.updatedDescriptor?.let { OutlinedButton( onClick = { onEvent(DescriptorViewModel.Event.UpdateDescriptor) }, diff --git a/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/run/RunViewModel.kt b/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/run/RunViewModel.kt index 5e8818cd..1e541fe7 100644 --- a/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/run/RunViewModel.kt +++ b/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/run/RunViewModel.kt @@ -30,7 +30,7 @@ import org.ooni.probe.ui.shared.SelectableItem class RunViewModel( onBack: () -> Unit, - getTestDescriptors: () -> Flow>, + getTestDescriptors: (Boolean?) -> Flow>, shouldShowVpnWarning: suspend () -> Boolean, private val preferenceRepository: PreferenceRepository, startBackgroundRun: (RunSpecification) -> Unit, @@ -45,7 +45,7 @@ class RunViewModel( init { combine( - getTestDescriptors(), + getTestDescriptors(false), collapsedDescriptorsKeys, ::Pair, ).flatMapLatest { (descriptors, collapsedDescriptorsKeys) -> diff --git a/composeApp/src/commonMain/sqldelight/org/ooni/probe/data/TestDescriptor.sq b/composeApp/src/commonMain/sqldelight/org/ooni/probe/data/TestDescriptor.sq index ab6d2645..3fbac148 100644 --- a/composeApp/src/commonMain/sqldelight/org/ooni/probe/data/TestDescriptor.sq +++ b/composeApp/src/commonMain/sqldelight/org/ooni/probe/data/TestDescriptor.sq @@ -71,7 +71,7 @@ setAutoUpdate: UPDATE TestDescriptor SET auto_update = ? WHERE runId = ?; selectAll: -SELECT * FROM TestDescriptor; +SELECT * FROM TestDescriptor WHERE (is_expired IS NULL OR is_expired = :isExpired) OR (:isExpired IS NULL); selectByRunIds: SELECT * FROM TestDescriptor WHERE runId IN ?;