From a8b473a33bfdbebba71e38401d38abf15fd98a42 Mon Sep 17 00:00:00 2001 From: Abe White Date: Mon, 12 Aug 2024 15:04:42 -0500 Subject: [PATCH] Support .onOpenURL --- README.md | 4 +++ .../SkipUI/SkipUI/System/UserActivity.swift | 30 +++++++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0ea431c0..7a8f21d7 100644 --- a/README.md +++ b/README.md @@ -1243,6 +1243,10 @@ Support levels: ✅ .onMove + + ✅ + .onOpenURL + ✅ .onReceive diff --git a/Sources/SkipUI/SkipUI/System/UserActivity.swift b/Sources/SkipUI/SkipUI/System/UserActivity.swift index 292edbf7..7bb3d14a 100644 --- a/Sources/SkipUI/SkipUI/System/UserActivity.swift +++ b/Sources/SkipUI/SkipUI/System/UserActivity.swift @@ -4,6 +4,14 @@ // under the terms of the GNU Lesser General Public License 3.0 // as published by the Free Software Foundation https://fsf.org +import Foundation +#if SKIP +import android.app.Activity +import android.content.Intent +import androidx.compose.runtime.SideEffect +import androidx.compose.ui.platform.LocalContext +#endif + extension View { @available(*, unavailable) public func userActivity(_ activityType: String, isActive: Bool = true, _ update: @escaping (Any /* NSUserActivity */) -> ()) -> some View { @@ -20,9 +28,27 @@ extension View { return self } - @available(*, unavailable) - public func onOpenURL(perform action: @escaping (URL) -> ()) -> some View { + public func onOpenURL(perform action: @escaping (URL) -> Void) -> some View { + #if SKIP + return ComposeModifierView(targetView: self) { context in + guard let activity = LocalContext.current as? Activity, let intent = activity.intent, intent.action == Intent.ACTION_VIEW else { + return ComposeResult.ok + } + guard let dataString = intent.dataString, let url = URL(string: dataString) else { + return ComposeResult.ok + } + SideEffect { + action(url) + // Clear the intent so that we don't process it on recompose. We also considered remembering the last + // processed intent in each `onOpenURL`, but then navigation to a new `onOpenURL` modifier would process + // any existing intent as new because it wouldn't be remembered for that modifier + activity.intent = nil + } + return ComposeResult.ok + } + #else return self + #endif } }