feat(android): open share links from a browser or the share sheet

A drive.proton.me/urls/ link opened from a browser, or text containing
one shared to the app, switches to Shares and opens the Add form with
the link filled in, fragment included. A playing episode moves to the
mini transport instead of covering the form. A recreated activity does
not offer the same link again.

The view filter is not autoVerify, since the domain is Proton's, so
Android only routes browser links here once "Open supported links" is
allowed in the app's settings; sharing works without that.
This commit is contained in:
nvrl committed 2026-10-03 03:59:41 +02:00
1 parent 47b33cdb91
commit 8a1807c262
6 files changed
+124 -4

No files matched your search

@@ -87,6 +87,8 @@ private enum class Destination(val label: String, val icon: ImageVector) {
fun ProtonStreamApp(
playerHost: LibmpvHost? = null,
inPictureInPicture: Boolean = false,
shareLink: String? = null,
onShareLinkTaken: () -> Unit = {},
model: AppViewModel = viewModel(
factory = AppViewModel.Factory(
LocalContext.current,
@@ -118,6 +120,16 @@ fun ProtonStreamApp(
PlayRequest(title, episodes, playingIndex.coerceIn(0, (episodes.size - 1).coerceAtLeast(0)))
}
// A link opened from a browser or shared from another app: show the Add
// form with it filled in. A playing episode keeps going in the mini
// transport rather than covering the form.
LaunchedEffect(shareLink) {
if (shareLink != null) {
destination = Destination.Shares
selectedTitleKey = null
if (playingTitleKey != null) playerMinimized = true
}
}
LaunchedEffect(state.message) {
state.message?.let {
snackbars.showSnackbar(it)
@@ -213,6 +225,8 @@ fun ProtonStreamApp(
model::repairShare,
model::refreshShare,
model::removeShare,
shareLink,
onShareLinkTaken,
body,
)
Destination.Downloads -> DownloadsScreen(
@@ -45,6 +45,8 @@ internal fun SharesScreen(
onRepair: (String, String, String?) -> Unit,
onRefresh: (String) -> Unit,
onRemove: (String) -> Unit,
incomingLink: String?,
onIncomingLinkTaken: () -> Unit,
padding: PaddingValues,
) {
var showAdd by remember { mutableStateOf(false) }
@@ -79,7 +81,13 @@ internal fun SharesScreen(
}
}
}
if (showAdd) AddShareDialog(onDismiss = { showAdd = false }, onAdd = onAdd)
if (showAdd || incomingLink != null) {
AddShareDialog(
initialUrl = incomingLink.orEmpty(),
onDismiss = { showAdd = false; onIncomingLinkTaken() },
onAdd = onAdd,
)
}
repairing?.let { share ->
RepairShareDialog(
share = share,
@@ -145,9 +153,13 @@ private fun RepairShareDialog(
}
@Composable
private fun AddShareDialog(onDismiss: () -> Unit, onAdd: (String, String, String?) -> Unit) {
private fun AddShareDialog(
initialUrl: String,
onDismiss: () -> Unit,
onAdd: (String, String, String?) -> Unit,
) {
var name by remember { mutableStateOf("") }
var url by remember { mutableStateOf("") }
var url by remember(initialUrl) { mutableStateOf(initialUrl) }
var password by remember { mutableStateOf("") }
AlertDialog(
onDismissRequest = onDismiss,