Skip to content

Commit

Permalink
feat: Add support for sharing a link to the OONI Probe app (#239)
Browse files Browse the repository at this point in the history
* feat: Add support for sharing a link to the OONI Probe app
  • Loading branch information
aanorbel authored Nov 5, 2024
1 parent 3926987 commit 9898b34
Show file tree
Hide file tree
Showing 14 changed files with 441 additions and 9 deletions.
16 changes: 16 additions & 0 deletions composeApp/src/androidMain/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,22 @@
android:scheme="ooni" />
</intent-filter>
</activity-alias>
<activity-alias
android:exported="true"
android:enabled="@string/ooni_run_enabled"
android:name=".ShareRunActivity"
android:targetActivity=".MainActivity">

<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />

<action android:name="${applicationId}.nettest" />

<data android:mimeType="text/plain" />
</intent-filter>

</activity-alias>

<provider
android:name="androidx.core.content.FileProvider"
Expand Down
15 changes: 14 additions & 1 deletion composeApp/src/androidMain/kotlin/org/ooni/probe/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,19 @@ class MainActivity : ComponentActivity() {
}

private fun manageIntent(intent: Intent) {
if (intent.action != Intent.ACTION_VIEW) return
when (intent.action) {
Intent.ACTION_VIEW -> manageOoniRun(intent)
Intent.ACTION_SEND -> manageSend(intent)
else -> return
}
}

private fun manageSend(intent: Intent) {
val url = intent.getStringExtra(Intent.EXTRA_TEXT) ?: return
deepLinkFlow.tryEmit(DeepLink.RunUrls(url))
}

private fun manageOoniRun(intent: Intent) {
val uri = intent.data ?: return
when (uri.host) {
"runv2",
Expand All @@ -61,6 +73,7 @@ class MainActivity : ComponentActivity() {
}

else -> {
deepLinkFlow.tryEmit(DeepLink.Error)
Logger.e { "Unknown deep link: $uri" }
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,4 +290,5 @@
<string name="filter_logs">Filter Logs</string>
<string name="results_limited_notice">Only the last %1$d results are shown</string>
<string name="auto_test_not_uploaded_limit">Skip after this amount of results failed to upload</string>
<string name="AddDescriptor_Toasts_Unsupported_Url">Unsupported URL</string>
</resources>
11 changes: 11 additions & 0 deletions composeApp/src/commonMain/kotlin/org/ooni/probe/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import co.touchlab.kermit.Logger
import ooniprobe.composeapp.generated.resources.AddDescriptor_Toasts_Unsupported_Url
import ooniprobe.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.getString
import org.jetbrains.compose.ui.tooling.preview.Preview
import org.ooni.probe.data.models.DeepLink
import org.ooni.probe.di.Dependencies
Expand Down Expand Up @@ -111,6 +114,14 @@ fun App(
navController.navigate("add-descriptor/${deepLink.id}")
onDeeplinkHandled()
}
is DeepLink.RunUrls -> {
navController.navigate(Screen.ChooseWebsites(deepLink.url).route)
onDeeplinkHandled()
}
DeepLink.Error -> {
snackbarHostState.showSnackbar(getString(Res.string.AddDescriptor_Toasts_Unsupported_Url))
onDeeplinkHandled()
}
null -> Unit
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@ package org.ooni.probe.data.models

sealed class DeepLink {
data class AddDescriptor(val id: String) : DeepLink()

data class RunUrls(val url: String) : DeepLink()

data object Error : DeepLink()
}
Original file line number Diff line number Diff line change
Expand Up @@ -390,10 +390,12 @@ class Dependencies(
fun chooseWebsitesViewModel(
onBack: () -> Unit,
goToDashboard: () -> Unit,
initialUrl: String?,
) = ChooseWebsitesViewModel(
onBack = onBack,
goToDashboard = goToDashboard,
startBackgroundRun = startSingleRunInner,
initialUrl = initialUrl,
)

fun dashboardViewModel(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,19 @@ class ChooseWebsitesViewModel(
onBack: () -> Unit,
goToDashboard: () -> Unit,
startBackgroundRun: (RunSpecification) -> Unit,
initialUrl: String? = null,
) : ViewModel() {
private val events = MutableSharedFlow<Event>(extraBufferCapacity = 1)

private val _state = MutableStateFlow(State())
private val _state = MutableStateFlow(
State(
websites = listOf(
initialUrl?.let {
WebsiteItem(url = it, hasError = !it.isValidUrl())
} ?: WebsiteItem(),
),
),
)
val state = _state.asStateFlow()

init {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ fun Navigation(
goToReviewDescriptorUpdates = {
navController.safeNavigate(Screen.ReviewUpdates)
},
goToChooseWebsites = { navController.navigate(Screen.ChooseWebsites.route) },
goToChooseWebsites = { navController.safeNavigate(Screen.ChooseWebsites()) },
)
}
val state by viewModel.state.collectAsState()
Expand All @@ -296,10 +296,15 @@ fun Navigation(
ReviewUpdatesScreen(state, viewModel::onEvent)
}

composable(route = Screen.ChooseWebsites.route) { entry ->
composable(
route = Screen.ChooseWebsites.NAV_ROUTE,
arguments = Screen.ChooseWebsites.ARGUMENTS,
) { entry ->
val url = entry.arguments?.getString("url")
val viewModel = viewModel {
dependencies.chooseWebsitesViewModel(
onBack = { navController.goBack() },
initialUrl = url.decodeUrlFromBase64(),
goToDashboard = {
navController.goBackTo(Screen.Dashboard, inclusive = false)
},
Expand Down Expand Up @@ -342,7 +347,7 @@ private fun NavController.goBackAndNavigateToMain(screen: Screen) {
navigateToMainScreen(screen)
}

private fun NavController.safeNavigate(screen: Screen) {
fun NavController.safeNavigate(screen: Screen) {
if (!isResumed()) return
navigate(screen.route)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,21 @@ sealed class Screen(
}
}

data class ChooseWebsites(
val url: String? = null,
) : Screen("choose-websites?url=${url.encodeUrlToBase64()}") {
companion object {
const val NAV_ROUTE = "choose-websites?url={url}"
val ARGUMENTS = listOf(
navArgument("url") {
type = NavType.StringType
defaultValue = null
nullable = true
},
)
}
}

data class Descriptor(
val descriptorKey: String,
) : Screen("descriptors/$descriptorKey") {
Expand All @@ -91,6 +106,4 @@ sealed class Screen(
}

data object ReviewUpdates : Screen("review-updates")

data object ChooseWebsites : Screen("choose-websites")
}
Loading

0 comments on commit 9898b34

Please sign in to comment.