-
-
Notifications
You must be signed in to change notification settings - Fork 271
feat(app): Implement deep linking for repository details #246
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
859ea92
9f18790
7ae63cf
1314f0b
cdc0f61
ace8819
5e0c9d0
52dd28a
aae5594
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,26 +3,47 @@ package zed.rainxch.githubstore | |
| import androidx.compose.foundation.isSystemInDarkTheme | ||
| import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi | ||
| import androidx.compose.runtime.Composable | ||
| import androidx.compose.runtime.LaunchedEffect | ||
| import androidx.compose.runtime.getValue | ||
| import androidx.lifecycle.compose.collectAsStateWithLifecycle | ||
| import androidx.navigation.compose.rememberNavController | ||
| import org.jetbrains.compose.ui.tooling.preview.Preview | ||
| import org.koin.compose.viewmodel.koinViewModel | ||
| import zed.rainxch.core.presentation.theme.GithubStoreTheme | ||
| import zed.rainxch.core.presentation.utils.ApplyAndroidSystemBars | ||
| import zed.rainxch.githubstore.app.deeplink.DeepLinkDestination | ||
| import zed.rainxch.githubstore.app.deeplink.DeepLinkParser | ||
| import zed.rainxch.githubstore.app.navigation.AppNavigation | ||
| import zed.rainxch.githubstore.app.navigation.GithubStoreGraph | ||
| import zed.rainxch.githubstore.app.components.RateLimitDialog | ||
|
|
||
| @OptIn(ExperimentalMaterial3ExpressiveApi::class) | ||
| @Composable | ||
| @Preview | ||
| fun App() { | ||
| fun App(deepLinkUri: String? = null) { | ||
| val viewModel: MainViewModel = koinViewModel() | ||
| val state by viewModel.state.collectAsStateWithLifecycle() | ||
|
|
||
| val navBackStack = rememberNavController() | ||
|
|
||
| LaunchedEffect(deepLinkUri) { | ||
| deepLinkUri?.let { uri -> | ||
| when (val destination = DeepLinkParser.parse(uri)) { | ||
| is DeepLinkDestination.Repository -> { | ||
| navBackStack.navigate( | ||
| GithubStoreGraph.DetailsScreen( | ||
| owner = destination.owner, | ||
| repo = destination.repo | ||
| ) | ||
| ) | ||
| } | ||
|
|
||
| DeepLinkDestination.None -> { /* ignore unrecognized deep links */ | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
Comment on lines
+29
to
+45
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Repeated identical deep link URIs won't re-trigger navigation.
Consider using a wrapper that includes a timestamp or incrementing counter to guarantee re-trigger: data class DeepLinkEvent(val uri: String, val timestamp: Long = System.currentTimeMillis())Alternatively, reset 🤖 Prompt for AI Agents |
||
|
|
||
| GithubStoreTheme( | ||
| fontTheme = state.currentFontTheme, | ||
| appTheme = state.currentColorTheme, | ||
|
|
@@ -31,19 +52,21 @@ fun App() { | |
| ) { | ||
| ApplyAndroidSystemBars(state.isDarkTheme) | ||
|
|
||
| if (state.showRateLimitDialog && state.rateLimitInfo != null) { | ||
| RateLimitDialog( | ||
| rateLimitInfo = state.rateLimitInfo, | ||
| isAuthenticated = state.isLoggedIn, | ||
| onDismiss = { | ||
| viewModel.onAction(MainAction.DismissRateLimitDialog) | ||
| }, | ||
| onSignIn = { | ||
| viewModel.onAction(MainAction.DismissRateLimitDialog) | ||
|
|
||
| navBackStack.navigate(GithubStoreGraph.AuthenticationScreen) | ||
| } | ||
| ) | ||
| if (state.showRateLimitDialog) { | ||
| state.rateLimitInfo?.let { | ||
| RateLimitDialog( | ||
| rateLimitInfo = it, | ||
| isAuthenticated = state.isLoggedIn, | ||
| onDismiss = { | ||
| viewModel.onAction(MainAction.DismissRateLimitDialog) | ||
| }, | ||
| onSignIn = { | ||
| viewModel.onAction(MainAction.DismissRateLimitDialog) | ||
|
|
||
| navBackStack.navigate(GithubStoreGraph.AuthenticationScreen) | ||
| } | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| AppNavigation( | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Claiming
github.comURLs without App Links verification is problematic.This intent filter intercepts
https://github.comURLs withoutandroid:autoVerify="true"and a corresponding/.well-known/assetlinks.jsonongithub.com(which you don't control). This causes:pathPattern:"/.*/..*"matches not just/{owner}/{repo}but also/{owner}/{repo}/issues,/{owner}/{repo}/tree/main/src/..., profile URLs like/{user}/stars, etc. Android'spathPatternregex is limited and can't constrain to exactly two segments.Consider removing this filter and instead relying solely on the custom
githubstore://scheme and your own domain (github-store.org). If you want to support GitHub URLs, implement a share-target or useACTION_SENDwith text filtering, which is opt-in by the user.🤖 Prompt for AI Agents