fix: iPhone app links open in external browser#150
Conversation
…e app - Replace target="_blank" external links with Tauri opener plugin in SimplifiedFooter.tsx - Fix "Learn more" button in Explainer.tsx to use opener plugin - Ensure external links open in device's default browser instead of new tabs - Add fallback to window.open() for non-Tauri environments - Keep Downloads link unchanged as it works correctly with internal routing Fixes broken links that only worked with long press on iPhone app 🤖 Generated with [Claude Code](https://claude.ai/code) Co-authored-by: Marks <marksftw@users.noreply.github.com>
Deploying maple with
|
| Latest commit: |
b0a97ce
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://084d26ff.maple-ca8.pages.dev |
| Branch Preview URL: | https://claude-issue-149-20250715-03.maple-ca8.pages.dev |
WalkthroughThe changes update external link handling in the Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Button (UI)
participant TauriOpener
participant Browser
User->>Button (UI): Click external link button
Button (UI)->>TauriOpener: Try to open URL via Tauri plugin
alt Tauri available
TauriOpener-->>User: URL opened in device browser
else Tauri not available
Button (UI)->>Browser: window.open(url, "_blank", "noopener,noreferrer")
Browser-->>User: URL opened in new tab
end
Assessment against linked issues
Assessment against linked issues: Out-of-scope changesNo out-of-scope changes found. Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Greptile Summary
This PR fixes a critical UX issue in the iPhone app where external links were only working with long-press gestures instead of normal taps. The changes primarily affect two components:
SimplifiedFooter.tsx: Replaces anchor tags with buttons using Tauri's opener pluginExplainer.tsx: Updates the "Learn more" button to use the same opener plugin pattern
The implementation intelligently handles both mobile and web environments by:
- Using Tauri's opener plugin as the primary mechanism to launch external URLs in the device's default browser
- Providing a fallback to
window.open()for web environments - Preserving internal routing for the Downloads link
The changes improve the iOS user experience while maintaining compatibility across all platforms.
Confidence score: 4/5
- This PR is safe to merge with standard testing
- The code changes are straightforward, well-implemented with proper error handling, and maintain backward compatibility
- Files needing attention:
SimplifiedFooter.tsx: Verify all external links are properly convertedExplainer.tsx: Ensure the Learn more button works in both mobile and web contexts
2 files reviewed, 3 comments
Edit PR Review Bot Settings | Greptile
| "Failed to open URL with Tauri opener, falling back to window.open:", | ||
| error | ||
| ); | ||
| window.open("https://blog.trymaple.ai", "_blank", "noopener,noreferrer"); |
There was a problem hiding this comment.
logic: ensure window.open call is in try-catch since it can throw in some environments
| const handleExternalLink = async (url: string) => { | ||
| try { | ||
| // Use Tauri opener plugin to open external URLs in the device's default browser | ||
| const { invoke } = await import("@tauri-apps/api/core"); |
There was a problem hiding this comment.
style: consider moving the import outside the function to avoid repeated dynamic imports on every click
| className="text-[hsl(var(--purple))] hover:text-[hsl(var(--purple))]/80 dark:text-[hsl(var(--blue))] dark:hover:text-[hsl(var(--blue))]/80 transition-colors" | ||
| <button | ||
| onClick={() => handleExternalLink("https://opensecret.cloud")} | ||
| className="text-[hsl(var(--purple))] hover:text-[hsl(var(--purple))]/80 dark:text-[hsl(var(--blue))] dark:hover:text-[hsl(var(--blue))]/80 transition-colors underline" |
There was a problem hiding this comment.
style: add role='link' to button for better accessibility since this behaves like a link
There was a problem hiding this comment.
Actionable comments posted: 2
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
frontend/src/components/Explainer.tsx(1 hunks)frontend/src/components/SimplifiedFooter.tsx(2 hunks)
🔇 Additional comments (1)
frontend/src/components/SimplifiedFooter.tsx (1)
19-24: Excellent differentiation between internal and external links.The conversion of external links to buttons while preserving the internal Downloads link as an anchor demonstrates good understanding of the requirements. The styling is properly maintained across all converted elements.
Also applies to: 33-44
|
@claude fix the code review comments |
|
Claude finished @marksftw's task —— View job ✅ Code Review Comments FixedAll issues identified in the code review have been successfully addressed: Todo List:
Changes Made:
Files Modified:
All changes have been committed and pushed to the PR branch. The code now follows DRY principles, has proper error handling, and improved accessibility. |
- Create shared openExternalLink utility function to eliminate code duplication - Add proper error handling with try-catch around window.open fallback - Add role='link' accessibility attributes to external link buttons - Update Explainer.tsx and SimplifiedFooter.tsx to use shared utility - Addresses code review feedback for better maintainability and accessibility Co-authored-by: Marks <marksftw@users.noreply.github.com>
There was a problem hiding this comment.
Greptile Summary
A new utility file externalLinks.ts has been added to centralize the link handling logic. This is a good architectural improvement that:
- Provides a single source of truth for external link handling
- Implements proper error handling for both Tauri and web environments
- Uses async/await pattern for better error management
- Includes helpful console warnings for debugging
The addition of this utility file makes the codebase more maintainable and reduces duplicate code across components.
Confidence score: 5/5
- This PR is very safe to merge as it isolates link handling functionality
- The score is high because the changes follow best practices with proper error handling, logging, and clear separation of concerns
- Files needing attention:
externalLinks.ts: Core functionality for link handling
3 files reviewed, no comments
Edit PR Review Bot Settings | Greptile
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
frontend/src/utils/externalLinks.ts (1)
12-20: Consider adding URL validation for security.The error handling and fallback mechanism is well-implemented with appropriate logging levels. However, consider adding URL validation to prevent potential security issues.
export const openExternalLink = async (url: string): Promise<void> => { + // Basic URL validation + if (!url || typeof url !== 'string') { + throw new Error('Invalid URL provided'); + } + + try { + new URL(url); // Validates URL format + } catch { + throw new Error('Invalid URL format'); + } + try { // Use Tauri opener plugin to open external URLs in the device's default browser const { invoke } = await import("@tauri-apps/api/core");
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
frontend/src/components/Explainer.tsx(2 hunks)frontend/src/components/SimplifiedFooter.tsx(2 hunks)frontend/src/utils/externalLinks.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- frontend/src/components/SimplifiedFooter.tsx
- frontend/src/components/Explainer.tsx
🔇 Additional comments (2)
frontend/src/utils/externalLinks.ts (2)
1-6: LGTM: Clear and comprehensive documentation.The JSDoc comment provides clear documentation of the function's purpose, parameter, and behavior, including the fallback mechanism.
7-11: LGTM: Proper Tauri integration with dynamic import.The implementation correctly uses dynamic import for the Tauri API, which prevents issues in non-Tauri environments, and follows the proper pattern for invoking the opener plugin.
|
@TestFlight build |
|
🚀 TestFlight deployment triggered! Check the Actions tab for progress. |
|
✅ TestFlight deployment completed successfully! |
|
@claude this isn't correct. You should be checking for iOS before trying to access that Tauri opener plugin. Check the other instances of that plugin. |
|
Claude finished @AnthonyRonning's task —— View job ✅ Fixed iOS Platform Check IssueYou're absolutely right! The implementation has been fixed to properly check for iOS before using the Tauri opener plugin. Todo List:
Problem Identified:The current implementation directly tried to use the Tauri opener plugin without checking if we're in a Tauri environment and on iOS. Looking at other implementations (like
Fixed Implementation:Updated
Commands Run:
Changes Committed:
The external links will now work correctly across all platforms with proper iOS detection! |
Only use the Tauri opener plugin when running on iOS in a Tauri environment, falling back to window.open for all other platforms and environments. Co-authored-by: Anthony <AnthonyRonning@users.noreply.github.com>
There was a problem hiding this comment.
Greptile Summary
The latest changes show updates to the UI components (SimplifiedFooter and Explainer) to implement the new externalLinks utility. The changes ensure consistent link behavior across the application by:
- Converting HTML anchor tags to buttons with click handlers
- Removing
target="_blank"attributes that were causing issues - Maintaining accessibility and visual styling while changing the underlying implementation
PR Description Notes:
- The PR description accurately reflects the implementation details
- The changes align well with issue #149's requirements
Confidence score: 5/5
- The PR is very safe to merge as it completes the link handling improvements
- The implementation maintains all existing styling while fixing the core functionality issue
- Files needing attention:
SimplifiedFooter.tsxandExplainer.tsx: Verify that button styling matches the original link appearance
1 file reviewed, 2 comments
Edit PR Review Bot Settings | Greptile
| export const openExternalLink = async (url: string): Promise<void> => { | ||
| try { | ||
| // Check if we're in a Tauri environment first | ||
| const { isTauri } = await import("@tauri-apps/api/core"); |
There was a problem hiding this comment.
style: dynamically importing isTauri could be moved outside function to avoid performance overhead on every link click
| // Final fallback if everything fails | ||
| console.warn("Failed to open URL with Tauri opener, falling back to window.open:", error); | ||
| try { | ||
| window.open(url, "_blank", "noopener,noreferrer"); |
There was a problem hiding this comment.
style: second window.open call unnecessarily repeats code from line 27 - consider extracting to shared function
|
this is slop code ill do it later |
Fixes #149
This PR fixes the broken website links at the bottom of the iPhone app that only worked with long press.
Changes
target="_blank"external links with Tauri opener plugin in SimplifiedFooter.tsxThe links now work with normal tap on iPhone and open in Safari as expected!
Generated with Claude Code
Summary by CodeRabbit
New Features
Style