fix: file link in markdown now opens a file sheet and fix ipad navigation issue#55
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Pull request overview
This PR improves link-handling and navigation consistency across desktop and mobile: markdown “local file” links now open an in-app file preview (desktop via inspector sheet; mobile via a remote file fetch + preview sheet), and mobile navigation is hardened against “pending session id → real session id” redirects (notably impacting iPad split-view flows). It also adds diff change navigation controls and standardizes mobile sheet presentation behavior.
Changes:
- Add
LocalFileLinkparsing +openURLinterception to open local file previews instead of handing local-looking links to the system browser. - Implement a mobile remote-file preview flow over the existing sync protocol (
remote_file_request/remote_file_result) and add a new preview sheet UI. - Improve session-id redirect handling (mock relay + mobile state) and extend diff UI with “previous/next change” navigation plus new tests.
Reviewed changes
Copilot reviewed 54 out of 55 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| RxCodeUITests/LocalAIProviderAcceptanceTests.swift | Seeds briefing content for UI tests and adds a briefing “start new chat” acceptance step. |
| RxCodeMobileUITests/Mock/MockRelayServer.swift | Simulates pending session IDs and delayed redirects to better cover navigation regressions. |
| RxCodeMobileUITests/iPhoneNavigationUITests.swift | Strengthens assertions to ensure messages remain visible after snapshot settle. |
| RxCodeMobileUITests/iPadNavigationUITests.swift | Strengthens assertions to ensure messages remain visible after snapshot settle in split view. |
| RxCodeMobile/Views/ThreadTodoSheet.swift | Applies standardized mobile sheet presentation modifier. |
| RxCodeMobile/Views/ThreadChangesSheet.swift | Adds change navigation UI/state and forwards navigation requests into diff views. |
| RxCodeMobile/Views/SyncLoadingView.swift | Refactors “Pair New Mac” button into a reusable view builder and shows it in loading UI. |
| RxCodeMobile/Views/SessionsList.swift | Applies standardized sheet presentation to the New Thread sheet. |
| RxCodeMobile/Views/RootView.swift | Applies standardized sheet presentation to onboarding/settings sheets. |
| RxCodeMobile/Views/RenameThreadSheet.swift | Migrates to standardized sheet presentation modifier. |
| RxCodeMobile/Views/QueuedMessagesSheet.swift | Migrates to standardized sheet presentation modifier. |
| RxCodeMobile/Views/ProjectsSidebar.swift | Migrates remote folder picker sheet to standardized sheet presentation modifier. |
| RxCodeMobile/Views/PermissionApprovalSheet.swift | Migrates to standardized sheet presentation modifier (with detents). |
| RxCodeMobile/Views/OnboardingView.swift | Applies standardized sheet presentation behavior to onboarding flows. |
| RxCodeMobile/Views/NewThreadSheet.swift | Migrates to standardized sheet presentation modifier. |
| RxCodeMobile/Views/MobileSkillMarketView.swift | Migrates git source sheet to standardized sheet presentation modifier. |
| RxCodeMobile/Views/MobileSheetPresentationModifier.swift | Introduces a shared modifier for consistent iOS sheet detents/drag/dismiss behavior. |
| RxCodeMobile/Views/MobileSettingsView.swift | Migrates nested onboarding sheet to standardized sheet presentation modifier. |
| RxCodeMobile/Views/MobileRunProfileEditorView.swift | Migrates picker sheet to standardized sheet presentation modifier. |
| RxCodeMobile/Views/MobileRemoteFilePreviewSheet.swift | New sheet that renders remotely-fetched file contents using DiffView. |
| RxCodeMobile/Views/MobileQuestionSheet.swift | Migrates to standardized sheet presentation modifier (with detents). |
| RxCodeMobile/Views/MobileMCPServersView.swift | Migrates add/edit sheets to standardized sheet presentation modifier. |
| RxCodeMobile/Views/MobileChatView.swift | Intercepts local file links, subscribes using resolved session IDs, and uses redirect-aware selectors. |
| RxCodeMobile/Views/MobileBriefingDetailView.swift | Migrates new thread sheet to standardized sheet presentation modifier. |
| RxCodeMobile/State/MobileAppState+Sync.swift | Resolves redirected session IDs for sync requests and adds remote file request API. |
| RxCodeMobile/State/MobileAppState+Intents.swift | Adds session-id resolution helpers and uses them across outbound intents. |
| RxCodeMobile/State/MobileAppState+Inbound.swift | Handles remote file results and tracks session-id redirects from session updates. |
| RxCodeMobile/State/MobileAppState.swift | Adds published state for session-id redirects and remote file request lifecycle. |
| RxCodeMobile/Resources/Localizable.xcstrings | Adds string keys used by new mobile file preview + diff navigation UI. |
| RxCode/Views/Sidebar/FileInspectorView.swift | Adds an “Open in Editor” menu for detected external editors + Finder reveal. |
| RxCode/Views/Sidebar/BriefingView.swift | Adds accessibility identifier for the briefing group actions button (UI test hook). |
| RxCode/Services/MobileSyncService+EventDispatch.swift | Dispatches remote_file_request payloads to the app via NotificationCenter. |
| RxCode/Services/MobileSyncService.swift | Adds notification name for remote file request events. |
| RxCode/Resources/Localizable.xcstrings | Adds string key(s) for new desktop UI text. |
| RxCode/App/RxCodeApp.swift | Centralizes markdown link handling; opens local file links in the inspector sheet. |
| RxCode/App/AppState+MobileSync.swift | Adds observer wiring for remote file requests coming from mobile. |
| RxCode/App/AppState+MobileSnapshots.swift | Implements remote-file read + reply (with project-root allowlist) for mobile previews. |
| RxCode/App/AppState+Lifecycle.swift | Adds UI-test-only seeding for briefing/thread summary content. |
| RxCode/App/AppState+CrossProject.swift | Improves draft/pending session redirect handling and broadcasts redirects to mobile. |
| RxCode.xcodeproj/project.pbxproj | Normalizes project file formatting for test file entries. |
| Packages/Tests/DiffViewTests/GutterLayoutTests.swift | Adds test coverage for horizontal scroll body width calculation. |
| Packages/Tests/DiffViewTests/DiffNavigationTests.swift | New tests for diff change-block targeting logic. |
| Packages/Sources/RxCodeSync/Protocol/Payload+Sessions.swift | Adds remote file request/result payload types to the sync protocol. |
| Packages/Sources/RxCodeSync/Protocol/Payload.swift | Adds new payload cases and codable wiring for remote file request/result. |
| Packages/Sources/RxCodeCore/Utilities/LocalFileLink.swift | New utility to parse local file links (path + optional line/column). |
| Packages/Sources/RxCodeChatKit/ToolResultView.swift | Applies consistent sheet dismissal behavior on iOS. |
| Packages/Sources/RxCodeChatKit/SlashCommandBar.swift | Applies consistent sheet dismissal behavior on iOS for command detail/manager sheets. |
| Packages/Sources/RxCodeChatKit/MobileSheetPresentationModifier.swift | New iOS-only modifier to hide drag indicator + disable interactive dismiss. |
| Packages/Sources/RxCodeChatKit/MessageBubble.swift | Applies consistent sheet dismissal behavior for image preview sheet. |
| Packages/Sources/RxCodeChatKit/InputBarView.swift | Applies consistent sheet dismissal behavior for attachment/command sheets. |
| Packages/Sources/RxCodeChatKit/FileDiffView.swift | Adds previous/next change navigation UI and state plumbing into DiffView. |
| Packages/Sources/RxCodeChatKit/ChangeDiffView.swift | Extends initializer to pass navigation requests/state through to DiffView. |
| Packages/Sources/DiffView/DiffView.swift | Adds change navigation API, scroll targeting, optional diff markers, and scroll-width calculation. |
| Packages/Sources/DiffView/DiffLine.swift | Marks DiffLine and members nonisolated under default MainActor isolation. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| func applySessionUpdate(_ update: SessionUpdatePayload) { | ||
| if let previous = update.previousSessionID, previous != update.sessionID { | ||
| sessionIDRedirects[previous] = update.sessionID | ||
| for (stale, target) in sessionIDRedirects where target == previous { |
| func requestRemoteFile(path: String, line: Int?) async { | ||
| guard isPaired else { | ||
| remoteFileResult = RemoteFileResultPayload( | ||
| clientRequestID: UUID(), | ||
| path: path, | ||
| name: URL(fileURLWithPath: path).lastPathComponent, | ||
| line: line, | ||
| ok: false, | ||
| errorMessage: String(localized: "Not connected to your Mac.") | ||
| ) | ||
| return | ||
| } |
| nonisolated private static func isPath(_ path: String, underAnyProject projectPaths: [String]) -> Bool { | ||
| let standardizedPath = URL(fileURLWithPath: path).standardizedFileURL.path | ||
| return projectPaths.contains { projectPath in | ||
| let root = URL(fileURLWithPath: projectPath).standardizedFileURL.path | ||
| return standardizedPath == root || standardizedPath.hasPrefix(root + "/") | ||
| } |
| @MainActor | ||
| private func openMarkdownLink(_ url: URL, in windowState: WindowState) -> OpenURLAction.Result { | ||
| if let fileLink = LocalFileLink.parse(url) { | ||
| let fileName = URL(fileURLWithPath: fileLink.path).lastPathComponent | ||
| windowState.inspectorFile = PreviewFile( | ||
| path: fileLink.path, | ||
| name: fileName.isEmpty ? fileLink.path : fileName | ||
| ) | ||
| return .handled |
| .sheet(isPresented: $showingNewThread) { | ||
| NewThreadSheet(projectID: projectID) { newSessionID in | ||
| selected = newSessionID | ||
| } | ||
| .environmentObject(state) | ||
| .mobileSheetPresentation() | ||
| } |
|
🎉 This PR is included in version 1.11.1 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
No description provided.