Skip to content

Deep-Linking (PARTIAL)#145

Merged
RyanCheung555 merged 9 commits intomainfrom
abby/deep-linking
Apr 27, 2026
Merged

Deep-Linking (PARTIAL)#145
RyanCheung555 merged 9 commits intomainfrom
abby/deep-linking

Conversation

@AbigailLabanok
Copy link
Copy Markdown
Contributor

@AbigailLabanok AbigailLabanok commented Apr 27, 2026

Overview

Added Linking Between Navi & Eatery/Uplift

Changes Made

  • added IntentUtils file with openDeepLink() function inside that takes you into another appdev app from navi based on the package passed in as a parameter (if that app is not downloaded on someone's phone, then it will direct you to the appstore page of that app)
  • added onDeepLinkClick parameter into onClicks within EateryDetailsContent + GymDetailsContent
  • passed in the openDeepLink() function to these parameters in DetailedPlaceSheetContent

Test Coverage

  • Manual Testing on a medium phone using the ecosystem build
  • Did testing where outside apps were downloaded (uplift/eatery) and where they weren't

Next Steps (delete if not applicable)

  • need to finish deep-linking so that it actually deep-links into the specific page in eatery/uplift for that eatery or gym

Related PRs or Issues (delete if not applicable)

Screenshots (delete if not applicable)

Clicking On Eatery Link (Eatery Installed on Phone)
Screen_recording_20260426_202257.webm
Clicking On Uplift Link (Uplift Installed on Phone)
Screen_recording_20260426_202354.webm
Clicking On Eatery Link (Eatery NOT Installed on Phone)
Screen_recording_20260426_202556.webm
Clicking On Uplit Link (Uplift NOT Installed on Phone)
Screen_recording_20260426_202710.webm

Summary by CodeRabbit

  • New Features

    • Eatery and gym detail screens now have clickable deep-link buttons that open the corresponding external apps (with Play Store fallback if not installed).
    • App manifest updated to enable direct linking to those external apps.
  • Improvements

    • Distance-based sorting refined to use the user’s current location for more accurate ordering.
  • Chores

    • App version bumped (user-visible version update).

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 27, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 814aa887-f1cb-4672-a669-26a844fbc4ef

📥 Commits

Reviewing files that changed from the base of the PR and between d0bc7a3 and f994c10.

📒 Files selected for processing (5)
  • app/build.gradle.kts
  • app/src/main/AndroidManifest.xml
  • app/src/main/java/com/cornellappdev/transit/ui/viewmodels/HomeViewModel.kt
  • app/src/main/java/com/cornellappdev/transit/util/RouteOptionsDisplayProcessor.kt
  • app/src/main/java/com/cornellappdev/transit/util/TransitConstants.kt

📝 Walkthrough

Walkthrough

Adds deep-link launch UI for eatery and gym details with Play Store fallback and package visibility declarations; refactors HomeViewModel to pass explicit user location into distance sorting and introduces IntentUtils.openDeepLink for launching external apps.

Changes

Cohort / File(s) Summary
Manifest Configuration
app/src/main/AndroidManifest.xml
Adds a top-level <queries> block declaring visibility for two external packages; removes one blank line in launcher intent-filter.
Deep-Link UI Integration
app/src/main/java/com/cornellappdev/transit/ui/components/home/DetailedPlaceSheetContent.kt, app/src/main/java/com/cornellappdev/transit/ui/components/home/EateryDetailsContent.kt, app/src/main/java/com/cornellappdev/transit/ui/components/home/GymDetailsContent.kt
Wires onDeepLinkClick callbacks into detail composables; wraps "view menu"/"view gym" text in clickable TextButton; uses LocalContext and forwards package IDs to the deep-link handler.
Deep-Link Utility
app/src/main/java/com/cornellappdev/transit/util/IntentUtils.kt
New IntentUtils with Context.openDeepLink(packageName) extension: attempts package launch, falls back to Play Store market:// intent, then to web Play Store, and logs failures.
Location-Based Sorting Refactor
app/src/main/java/com/cornellappdev/transit/ui/viewmodels/HomeViewModel.kt
libraryCardsFlow now combines with currentLocation; numericalDistanceToPlace and sortApiResponse signatures accept explicit userLocation; exclusions applied before sorting.
Version Bump
app/build.gradle.kts
Increments versionCode 10→11 and versionName "2.0"→"2.1".
Arrive-By Logic
app/src/main/java/com/cornellappdev/transit/util/RouteOptionsDisplayProcessor.kt, app/src/main/java/com/cornellappdev/transit/util/TransitConstants.kt
Removes ARRIVE_BY_CUTOFF_GRACE_MINUTES constant and tightens arrive-by filtering to use the cutoff strictly (no added grace).

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant Sheet as DetailedPlaceSheetContent
    participant Detail as Eatery/GymDetailsContent
    participant Intent as IntentUtils
    participant PM as PackageManager
    participant External as External App
    participant Store as Play Store

    User->>Sheet: Open place details
    Sheet->>Detail: Render with onDeepLinkClick callback
    User->>Detail: Tap "view menu"/"view gym"
    Detail->>Intent: openDeepLink(packageName)
    Intent->>PM: getLaunchIntentForPackage()
    alt App installed
        PM-->>Intent: launch intent
        Intent->>External: startActivity(launchIntent)
        External-->>User: app opens
    else App not installed
        PM-->>Intent: null
        Intent->>Store: ACTION_VIEW market://details?id=...
        alt Market app handles intent
            Store-->>User: Play Store opens
        else
            Intent->>Store: ACTION_VIEW https://play.google.com/...
            Store-->>User: Browser opens Play Store page
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • AndrewCheung360

Poem

🐰 I hopped through code with a joyful squeak,

Tapped menus that jump where the app paths speak,
If doors are closed, to the store I will steer,
Sorting the map so the closest is clear,
A rabbit’s small cheer for launches far and near. 🥕

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Deep-Linking (PARTIAL)' is partially related to the changeset. It identifies the main feature area but is vague by including '(PARTIAL)' which, while technically accurate per the description, doesn't clearly communicate the specific primary change to a reviewer scanning history. Consider a more specific title that better describes the primary change, such as 'Add partial deep-linking support for Eatery and Uplift apps' to improve clarity for future reference.
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed The pull request description includes Overview, Changes Made, Test Coverage, Next Steps, Related PRs/Issues, and Screenshots sections. All major required sections are present and substantively filled with details about the implementation, testing approach, and future work needed.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch abby/deep-linking

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (3)
app/src/main/java/com/cornellappdev/transit/ui/viewmodels/HomeViewModel.kt (2)

127-129: Stray blank lines.

Lines 128–129 are empty leftovers from the refactor; consider removing them.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/main/java/com/cornellappdev/transit/ui/viewmodels/HomeViewModel.kt`
around lines 127 - 129, The stray blank lines after the userLocation assignment
(val userLocation = location?.let { LatLng(it.latitude, it.longitude) }) in
HomeViewModel.kt should be removed to clean up the refactor; locate the
declaration of userLocation in the HomeViewModel class/constructor and delete
the extra empty lines so the surrounding code is compact and properly formatted.

56-78: Sort recomputes on every location emission.

libraryCardsFlow (and staticPlacesFlow) now re-sort the entire list every time currentLocation emits, which can be quite frequent for an active GPS feed. Consider applying .distinctUntilChanged() on the location source (or a coarse-grained version of it) before combining, so the work only happens when distance ordering can meaningfully change.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/main/java/com/cornellappdev/transit/ui/viewmodels/HomeViewModel.kt`
around lines 56 - 78, The combine using routeRepository.libraryFlow and
locationRepository.currentLocation currently re-sorts on every location emission
(causing excessive work); fix it by debouncing/coarsening the location stream
before combining—apply distinctUntilChanged (or map the LatLng to a
coarse-grained bucket/rounded coordinates) to locationRepository.currentLocation
and use that new flow in the combine that produces
libraryCardsFlow/staticPlacesFlow so numericalDistanceToPlace and the sorting
only run when location meaningfully changes; update references in the combine
block that calls numericalDistanceToPlace and toLibraryCardUiState accordingly.
app/src/main/java/com/cornellappdev/transit/ui/components/home/DetailedPlaceSheetContent.kt (1)

105-134: Extract hardcoded package names to constants.

"com.cornellappdev.android.eatery" and "com.cornellappdev.uplift" are duplicated as string literals here and must stay in sync with the <queries> entries in AndroidManifest.xml. Consider exposing them as const val (e.g., in IntentUtils) so there is a single source of truth.

♻️ Suggested change
+// In IntentUtils.kt
+object IntentUtils {
+    const val EATERY_PACKAGE = "com.cornellappdev.android.eatery"
+    const val UPLIFT_PACKAGE = "com.cornellappdev.uplift"
+    ...
+}
-                            context.openDeepLink("com.cornellappdev.android.eatery")
+                            context.openDeepLink(IntentUtils.EATERY_PACKAGE)
...
-                            context.openDeepLink("com.cornellappdev.uplift")
+                            context.openDeepLink(IntentUtils.UPLIFT_PACKAGE)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@app/src/main/java/com/cornellappdev/transit/ui/components/home/DetailedPlaceSheetContent.kt`
around lines 105 - 134, Two hardcoded deep-link package name string literals
("com.cornellappdev.android.eatery" and "com.cornellappdev.uplift") are
duplicated; extract them into single const vals (e.g., add const val
EATERY_PACKAGE and UPLIFT_PACKAGE in an existing IntentUtils or similar utility
object) and replace the literals used in context.openDeepLink calls in
DetailedPlaceSheetContent (references: context.openDeepLink,
LibraryDetailsContent/GymDetailsContent invocation sites) to use those constants
so the package names remain a single source of truth and stay in sync with
AndroidManifest <queries>.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/src/main/java/com/cornellappdev/transit/util/IntentUtils.kt`:
- Line 20: The Play Store fallback URL contains a stray closing brace after the
package name in the startActivity(Intent(Intent.ACTION_VIEW, "...".toUri()))
call; remove the extra '}' so the interpolated string is
"https://play.google.com/store/apps/details?id=$packageName" (i.e., change the
URI passed to Intent.ACTION_VIEW to use id=$packageName without the trailing
brace) to restore a valid Play Store URL.
- Around line 14-23: The else-branch in IntentUtils.kt can crash and swallows
exceptions: wrap the outer fallback startActivity call in a try/catch for
ActivityNotFoundException, log the caught exception (instead of ignoring it),
and ensure both Intents (the market Intent created in this block and the HTTPS
fallback Intent) have FLAG_ACTIVITY_NEW_TASK added so the helper is safe to call
with an Application Context; update the catch to log via your logger/context
(e.g., processLogger or Log) and avoid rethrowing so failures are diagnosable
and the app won’t crash when no resolver exists.

---

Nitpick comments:
In
`@app/src/main/java/com/cornellappdev/transit/ui/components/home/DetailedPlaceSheetContent.kt`:
- Around line 105-134: Two hardcoded deep-link package name string literals
("com.cornellappdev.android.eatery" and "com.cornellappdev.uplift") are
duplicated; extract them into single const vals (e.g., add const val
EATERY_PACKAGE and UPLIFT_PACKAGE in an existing IntentUtils or similar utility
object) and replace the literals used in context.openDeepLink calls in
DetailedPlaceSheetContent (references: context.openDeepLink,
LibraryDetailsContent/GymDetailsContent invocation sites) to use those constants
so the package names remain a single source of truth and stay in sync with
AndroidManifest <queries>.

In `@app/src/main/java/com/cornellappdev/transit/ui/viewmodels/HomeViewModel.kt`:
- Around line 127-129: The stray blank lines after the userLocation assignment
(val userLocation = location?.let { LatLng(it.latitude, it.longitude) }) in
HomeViewModel.kt should be removed to clean up the refactor; locate the
declaration of userLocation in the HomeViewModel class/constructor and delete
the extra empty lines so the surrounding code is compact and properly formatted.
- Around line 56-78: The combine using routeRepository.libraryFlow and
locationRepository.currentLocation currently re-sorts on every location emission
(causing excessive work); fix it by debouncing/coarsening the location stream
before combining—apply distinctUntilChanged (or map the LatLng to a
coarse-grained bucket/rounded coordinates) to locationRepository.currentLocation
and use that new flow in the combine that produces
libraryCardsFlow/staticPlacesFlow so numericalDistanceToPlace and the sorting
only run when location meaningfully changes; update references in the combine
block that calls numericalDistanceToPlace and toLibraryCardUiState accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 35269a18-7493-41e5-982a-237693823bcb

📥 Commits

Reviewing files that changed from the base of the PR and between acc3cff and 838dcd3.

📒 Files selected for processing (7)
  • app/src/main/AndroidManifest.xml
  • app/src/main/java/com/cornellappdev/transit/ui/components/home/DetailedPlaceSheetContent.kt
  • app/src/main/java/com/cornellappdev/transit/ui/components/home/EateryDetailsContent.kt
  • app/src/main/java/com/cornellappdev/transit/ui/components/home/GymDetailsContent.kt
  • app/src/main/java/com/cornellappdev/transit/ui/viewmodels/HomeViewModel.kt
  • app/src/main/java/com/cornellappdev/transit/util/IntentUtils.kt
  • uplift-android

Comment thread app/src/main/java/com/cornellappdev/transit/util/IntentUtils.kt
Comment thread app/src/main/java/com/cornellappdev/transit/util/IntentUtils.kt Outdated
style = Style.heading2,
color = TransitBlue
color = TransitBlue,
modifier = Modifier.clickable(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can make this a TextButton instead of clickable text

style = Style.heading2,
color = TransitBlue
color = TransitBlue,
modifier = Modifier.clickable(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can make this a TextButton instead of clickable text

@AndrewCheung360
Copy link
Copy Markdown
Member

What is the uplift-android folder for?

@AbigailLabanok
Copy link
Copy Markdown
Contributor Author

What is the uplift-android folder for?

Sorry, one of my git commands caused a weird error and I didn't know why or what happened. I'm pretty sure that's what it was because it was talking about some uplift-anroid thing. Will delete

fun numericalDistanceToPlace(latitude: Double?, longitude: Double?): Double {
val currentLocationSnapshot = currentLocation.value
return if (currentLocationSnapshot != null && latitude != null && longitude != null) {
fun numericalDistanceToPlace(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably be private if only used in this vm. Can also potentially be moved into one of the util files to keep this vm leaner

Copy link
Copy Markdown
Member

@AndrewCheung360 AndrewCheung360 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Nice work!

@RyanCheung555 RyanCheung555 merged commit d1e2a3b into main Apr 27, 2026
1 check was pending
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants