feat(mobile): Capacitor app (iOS + Android) + mobile-responsive fixes - #11505
feat(mobile): Capacitor app (iOS + Android) + mobile-responsive fixes#11505nmgarza5 wants to merge 5 commits into
Conversation
…fixes Native iOS shell wrapping Onyx Cloud, plus mobile UX fixes for the end-user chat experience. Admin stays desktop. mobile/ (new; XcodeGen + xcodebuild; bundle app.onyx.ios): - SwiftUI WKWebView loading cloud.onyx.app with loading/offline states - Google SSO: mobile Safari UA to avoid reCAPTCHA disallowed_useragent - App icon; SwiftUI safe-area handling - Injected mobile.css: collapse sidebar on phones, dialogs scroll/fit, settings two-pane -> stacked, momentum scroll, wide-table scroll wrappers - Admin pages show a native "best viewed on desktop" notice via a JS->native route bridge (onyxNav message handler) web/ (responsive; also fixes web on mobile): - SidebarStateProvider: default collapsed on mobile when no saved preference - SettingsLayouts.Header: smaller top spacing on mobile
|
Preview Deployment
|
Greptile SummaryThis PR introduces a native iOS app (
Confidence Score: 4/5The web-side changes are safe to merge. The mobile CI workflow has a broken release path that will fail on any semver tag. The release-ios CI job uploads to TestFlight using xcrun altool --upload-app with Apple ID and app-specific password — an authentication method Apple retired in October 2023. Every release-tag build will fail at that step. The simulator build job and all web-side changes are unaffected and work correctly. .github/workflows/pr-ios-build.yml — the release-ios job TestFlight upload step needs to be replaced with App Store Connect API key auth. Important Files Changed
|
| NOTE: remove once the web/ responsive spacing fix (pt-4 md:pt-10) is deployed. */ | ||
| [aria-label="admin-page-title"] { | ||
| margin-top: -1.5rem !important; | ||
| } | ||
|
|
||
| /* End-user Settings is a desktop two-pane row (left tab nav + content). Stack it | ||
| vertically on mobile so the nav and content each get full width. */ | ||
| [data-testid="settings-left-tab-navigation"] { | ||
| min-width: 0 !important; | ||
| width: 100% !important; |
There was a problem hiding this comment.
Negative-margin workaround is now overcorrecting
The comment says "remove once the web/ responsive spacing fix (pt-4 md:pt-10) is deployed" — but that fix is being deployed in this same PR (components.tsx). Once this code lands, the settings header has pt-4 (16 px) on mobile instead of the old 2.5 rem spacer. Applying margin-top: -1.5rem (-24 px) to [aria-label="admin-page-title"] on top of only 16 px of padding results in the title being drawn ~8 px above the padded area, overlapping whatever precedes it. This rule should not be included now that the underlying spacing is corrected in the same changeset.
Prompt To Fix With AI
This is a comment left during a code review.
Path: mobile/Sources/mobile.css
Line: 44-53
Comment:
**Negative-margin workaround is now overcorrecting**
The comment says "remove once the web/ responsive spacing fix (`pt-4 md:pt-10`) is deployed" — but that fix is being deployed in this same PR (`components.tsx`). Once this code lands, the settings header has `pt-4` (16 px) on mobile instead of the old 2.5 rem spacer. Applying `margin-top: -1.5rem` (-24 px) to `[aria-label="admin-page-title"]` on top of only 16 px of padding results in the title being drawn ~8 px above the padded area, overlapping whatever precedes it. This rule should not be included now that the underlying spacing is corrected in the same changeset.
How can I resolve this? If you propose a fix, please make it concise.| import SwiftUI | ||
| import WebKit | ||
|
|
||
| let onyxURL = URL(string: "https://cloud.onyx.app")! |
There was a problem hiding this comment.
App is unconditionally bound to
cloud.onyx.app
The target URL is a compile-time constant with no override path for self-hosted deployments. Anyone running Onyx on-prem (single-tenant or multi-tenant) cannot use this app without forking and rebuilding. The repository's engineering rules call out that code must consider both cloud and self-hosted deployments. Even a ONYX_BASE_URL build setting (similar to how ONYX_PATH is already plumbed for QA paths) or a per-launch env var pattern would address this without adding runtime UI complexity.
Prompt To Fix With AI
This is a comment left during a code review.
Path: mobile/Sources/OnyxApp.swift
Line: 4
Comment:
**App is unconditionally bound to `cloud.onyx.app`**
The target URL is a compile-time constant with no override path for self-hosted deployments. Anyone running Onyx on-prem (single-tenant or multi-tenant) cannot use this app without forking and rebuilding. The repository's engineering rules call out that code must consider both cloud and self-hosted deployments. Even a `ONYX_BASE_URL` build setting (similar to how `ONYX_PATH` is already plumbed for QA paths) or a per-launch env var pattern would address this without adding runtime UI complexity.
How can I resolve this? If you propose a fix, please make it concise.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
|
|
||
| <div className="flex flex-col gap-6 px-4"> | ||
| {/* Smaller top gap on mobile; full desktop spacing at md+. */} | ||
| <div className="flex flex-col gap-6 px-4 pt-4 md:pt-10"> |
There was a problem hiding this comment.
Opal component modified without updating the Storybook story
SettingsHeader is an Opal layout component and the project rule requires the related story to be updated when a component changes. The existing story in SettingsLayouts.stories.tsx has no mobile-viewport story showing the new pt-4 / md:pt-10 responsive spacing. Adding a story with a mobile viewport (e.g. parameters: { viewport: { defaultViewport: 'mobile1' } }) would keep visual coverage accurate.
Rule Used: What: When modifying a frontend component (Opal, r... (source)
Prompt To Fix With AI
This is a comment left during a code review.
Path: web/lib/opal/src/layouts/settings/components.tsx
Line: 129
Comment:
**Opal component modified without updating the Storybook story**
`SettingsHeader` is an Opal layout component and the project rule requires the related story to be updated when a component changes. The existing story in `SettingsLayouts.stories.tsx` has no mobile-viewport story showing the new `pt-4` / `md:pt-10` responsive spacing. Adding a story with a mobile viewport (e.g. `parameters: { viewport: { defaultViewport: 'mobile1' } }`) would keep visual coverage accurate.
**Rule Used:** What: When modifying a frontend component (Opal, r... ([source](https://app.greptile.com/personal-org-210/-/custom-context?memory=01f53a66-6321-4d0a-b8c2-d6c3bc03b286))
How can I resolve this? If you propose a fix, please make it concise.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Mirrors the desktop build flow for the native iOS app: - PR / merge_group on mobile/** -> xcodegen + unsigned simulator build (compile check) - tag v*.*.* (non-beta) -> signed device archive + export + TestFlight upload Signing reuses the desktop mechanism (deployment.yml): Apple secrets pulled from AWS Secrets Manager via OIDC (deploy/apple-* keys) + certificate imported into a keychain; upload via altool with the existing APPLE_ID/APPLE_PASSWORD. iOS adds one secret, deploy/apple-ios-provisioning-profile (App Store profile for app.onyx.ios).
🖼️ Visual Regression Report
|
Side-by-side multi-model comparison is unusable at phone widths. Gate it off in ModelSelector (multiModelAllowed = false when isMobile), so a second model can't be added on mobile regardless of the workspace setting.
Replace the iOS-only SwiftUI WKWebView shell with a Capacitor project so one codebase targets iOS + Android. Loads cloud.onyx.app via server.url for now (will point at a mobile-first Opal build of web/ once those screens exist). - appId app.onyx.mobile (iOS bundle + Android package) - Google SSO: per-platform overrideUserAgent (mobile Safari/Chrome) to avoid reCAPTCHA disallowed_useragent in the web view - Capacitor 8 (SPM on iOS, no CocoaPods); native ios/ + android/ generated via `cap add` (gitignored), not committed - Removes the SwiftUI shell + the xcodegen-based pr-ios-build.yml (Capacitor CI lands next)
- PR/merge on mobile/**: cap add + unsigned iOS simulator build and Android debug assemble (compile checks on both platforms; ubuntu-latest ships the Android SDK/JDK) - tag v*.*.* (non-beta): signed iOS archive -> TestFlight via an App Store Connect API key (automatic signing, -allowProvisioningUpdates -> no manual cert/profile) API key pulled from AWS Secrets Manager (deploy/apple-asc-*), same store/OIDC as the desktop release. Inert until those secrets exist. Android Play release is a follow-up.
Description
Cross-platform Onyx mobile app via Capacitor (one codebase → iOS + Android), plus mobile UX fixes for the end-user chat experience. Admin stays desktop.
mobile/(Capacitor 8;appId app.onyx.mobile):cloud.onyx.appnow; will point at a mobile-first Opal build ofweb/(Figma) next.overrideUserAgent(avoids reCAPTCHAdisallowed_useragent).ios//android/generated viacap add(gitignored), SPM on iOS (no CocoaPods).pr-mobile-build.yml): iOS simulator + Android debug builds on PR; tagv*.*.*→ signed iOS archive → TestFlight via an App Store Connect API key (AWS Secrets Manager, same store/OIDC as desktop).web/(responsive; also fixes web on mobile):iOS verified building + running on the simulator. Remaining for release: add
deploy/apple-asc-*secrets; Apple app record; Android Play signing (follow-up).How Has This Been Tested?
Additional Options