feat(client): Added Capacitor Apps for iOS & Android#2723
feat(client): Added Capacitor Apps for iOS & Android#2723ayush-teon wants to merge 43 commits intoOutlineFoundation:masterfrom
Conversation
* Capacitor App added * Updated Comments * Updated Comments * Comments addressed and updated * Splash & Icon images removed * Update README.md
* Capacitor App added * Updated Comments * Updated Comments * Comments addressed and updated * Splash & Icon images removed * Update README.md * Streamlined package.json * Actions added to capacitor * Addressed package.json review comments. * Updated build and setup * Package updated * Setup and Build files updated * Setup file updated * Build and Setup files updated * Build, Setup and Package files updated * Build, Setup and Package files updated * Gitignore, Setup and Package files updated * Setup and Gradle settings updated * Updated Readme and title --------- Co-authored-by: Zahirul Islam <zislam.zais@gmail.com>
…lidation Nthlink/capacitor migration key validation
* UI fixes for Capacitor * UI fixes for Capacitor * Fixed Capacitor UI * Removed listeners * Event listeners updated * Update client/web/views/root_view/add_access_key_dialog/index.ts Co-authored-by: J. Yi <93548144+jyyi1@users.noreply.github.com> --------- Co-authored-by: J. Yi <93548144+jyyi1@users.noreply.github.com>
…and iOS (#7) * UI fixes for Capacitor * UI fixes for Capacitor * Fixed Capacitor UI * Removed listeners * Converted android project from Java to Kotlin * Imported OutlineAndroidLib and added Plugin for capactior * Imported OutlineAppleLib and added Plugin for capacitor * Minor Fixes * added capacitor outline plugin and web server * Fixed sidebar and root-app height issue for ios * Added capacitor outline plugin * Updated cordova and capacitor build issues * updated capacitor build for build params * updated capacitor life cycle to register plugin * Fixed status type casting for ios * updated entry point html for capacitor * Added capacitor android * es lint fixed * Updated ios build for vpn extension provisioning profile for PacketTunnel * Fixed ios splash screen and external link issue on ios and android * reverted settings.json * Added android build folder to gitignore * Added cordova outline plugin relative path to capacitor and removed capacitor plugin * Added staging build configuration for capacitor ios and android * fixed android language switch issue * revert b6a663a server manager formatting * revert b6a663a commit formatting * Added templates to resolve dependencies, added generic pluginRegisterListener method and added platform based rootPath * reverted 36e9c7b commit formatting * revert b6a663a commit formatting * added relative path for outline plugin * Mac Catalyst support added * Merge branch 'nthlink/capacitor-outline-cap-plugin', remote-tracking branch 'origin' into nthlink/capacitor-outline-debug * revert server manager changes * revert previous messages * reverted to latest merged master branch * revert outlinePlugin change in cordova plugins * Build updated * revert eslint.json * added closing body tag * removed logging tag from android main activity * added vpn extension symbolic link * updated copyright text * Bundle IDs updated * Spawn stream reverted * Updated build config for production * updated build action for android debug * added hot reloading for android and ios for development and updated page UI issues * reverted merged files * reverted UI files * added browser plugin for external link handling * App Groups bundle ID updated * removed patch package and revert lock file * added comments in AppDelegate and refactored sync files * removed ios integration * Icon added for android build * Update client/capacitor/README.md Co-authored-by: J. Yi <93548144+jyyi1@users.noreply.github.com> --------- Co-authored-by: Ayush Kumar Sethi <ayush@teon.com> Co-authored-by: Hasnainhanifse <hasnaindev786@gmail.com> Co-authored-by: J. Yi <93548144+jyyi1@users.noreply.github.com>
) * UI fixes for Capacitor * UI fixes for Capacitor * Fixed Capacitor UI * Removed listeners * Converted android project from Java to Kotlin * Imported OutlineAndroidLib and added Plugin for capactior * Imported OutlineAppleLib and added Plugin for capacitor * Minor Fixes * added capacitor outline plugin and web server * Fixed sidebar and root-app height issue for ios * Added capacitor outline plugin * Updated cordova and capacitor build issues * updated capacitor build for build params * updated capacitor life cycle to register plugin * Fixed status type casting for ios * updated entry point html for capacitor * Added capacitor android * es lint fixed * Updated ios build for vpn extension provisioning profile for PacketTunnel * Fixed ios splash screen and external link issue on ios and android * reverted settings.json * Added android build folder to gitignore * Added cordova outline plugin relative path to capacitor and removed capacitor plugin * Added staging build configuration for capacitor ios and android * fixed android language switch issue * revert b6a663a server manager formatting * revert b6a663a commit formatting * Added templates to resolve dependencies, added generic pluginRegisterListener method and added platform based rootPath * reverted 36e9c7b commit formatting * revert b6a663a commit formatting * added relative path for outline plugin * Mac Catalyst support added * Merge branch 'nthlink/capacitor-outline-cap-plugin', remote-tracking branch 'origin' into nthlink/capacitor-outline-debug * revert server manager changes * revert previous messages * reverted to latest merged master branch * revert outlinePlugin change in cordova plugins * Build updated * revert eslint.json * added closing body tag * removed logging tag from android main activity * added vpn extension symbolic link * updated copyright text * Bundle IDs updated * Spawn stream reverted * Updated build config for production * updated build action for android debug * added hot reloading for android and ios for development and updated page UI issues * reverted merged files * reverted UI files * added browser plugin for external link handling * App Groups bundle ID updated * removed patch package and revert lock file * added comments in AppDelegate and refactored sync files * Fixed iOS removed mac config * Code Signing Updated for Capacitor iOS * Bundle ID Updated for VPN extension on Capacitor iOS --------- Co-authored-by: Hasnainhanifse <hasnaindev786@gmail.com>
package.json
Outdated
| "eslint-plugin-prettier": "^5.2.1", | ||
| "eslint-plugin-storybook": "^0.8.0", | ||
| "gts": "^5.3.1", | ||
| "husky": "^9.1.7", |
There was a problem hiding this comment.
What is husky being used for?
There was a problem hiding this comment.
Husky is only added as a dev dependency right now; there’s no .husky config or hook scripts wired up in this repo, so it isn’t actively used yet.
There was a problem hiding this comment.
If it's not being used, please don't add. No dead code.
|
|
||
|
|
||
|
|
||
| # Capacitor generated assets (icons, splash screens) |
There was a problem hiding this comment.
What's the source for these?
Is there any actual transformation, or do we use the sources unmodified?
There was a problem hiding this comment.
Here's the source for Capacitor generated assets.
https://github.com/nthlink/outline-apps/tree/master/client/capacitor/assets
these sources are modified using following capacitor assets plugin in https://github.com/nthlink/outline-apps/blob/master/client/capacitor/build.action.mjs at line# 74.
await spawnStream('npx', 'capacitor-assets', 'generate');
| # Capacitor generated assets (icons, splash screens) | ||
| client/capacitor/android/app/src/main/res/drawable-*/ | ||
| client/capacitor/android/app/src/main/res/mipmap-*/ | ||
| client/capacitor/android/app/src/main/res/values/ic_launcher_background.xml |
There was a problem hiding this comment.
Do we also generate this?
There was a problem hiding this comment.
Yes, these are auto generated during build.
There was a problem hiding this comment.
When and how is this generated in the development workflow?
There was a problem hiding this comment.
similar to above here is the source for Capacitor generated assets.
https://github.com/nthlink/outline-apps/tree/master/client/capacitor/assets
these sources are modified using following capacitor assets plugin in https://github.com/nthlink/outline-apps/blob/master/client/capacitor/build.action.mjs at line# 74.
await spawnStream('npx', 'capacitor-assets', 'generate');
There was a problem hiding this comment.
Pull request overview
Adds Capacitor-based iOS/Android builds for the client, including native plugin bindings and build tooling to support mobile runtime behavior.
Changes:
- Introduces Capacitor workspace/package, native iOS/Android projects, and build/start actions for Capacitor targets
- Adds a Capacitor-native plugin interface (VPN/error reporting) plus webpack entry/config for Capacitor builds
- Updates web UI/layout to handle mobile safe-area insets and migrates ContactView select to Material Web components
Reviewed changes
Copilot reviewed 88 out of 98 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| package.json | Adds client/capacitor workspace and Husky dev dependency |
| infrastructure/platforms.ts | Adds Capacitor runtime/platform detection helpers |
| client/web/webpack_capacitor.mjs | Adds webpack config for Capacitor web build/dev server |
| client/web/views/root_view/root_header/index.ts | Adds safe-area inset handling for header |
| client/web/views/root_view/privacy_acknowledgement_dialog/index.ts | Fixes formatting/indentation (no logic change) |
| client/web/views/licenses_view/index.ts | Adds safe-area inset handling for licenses view |
| client/web/views/language_view/index.ts | Adds safe-area inset handling for language view |
| client/web/views/contact_view/index.ts | Migrates select UI to Material Web + safe-area padding updates |
| client/web/views/about_view/index.ts | Adds safe-area inset handling for about view |
| client/web/ui_components/app-root.js | Adjusts root path when running under Capacitor |
| client/web/index_capacitor.html | Adds Capacitor-specific HTML entrypoint |
| client/web/get_browser_webpack_config.mjs | Routes Capacitor platforms to webpack_capacitor config |
| client/web/app/url_interceptor.ts | Guards Cordova webintent usage for non-Cordova runtimes |
| client/web/app/plugin.cordova.ts | Adds runtime checks + listener registration helper for Cordova plugin |
| client/web/app/plugin.capacitor.ts | Adds Capacitor plugin exec + listener registration helpers |
| client/web/app/outline_server_repository/vpn.cordova.ts | Switches status listener registration to shared helper |
| client/web/app/outline_server_repository/vpn.capacitor.ts | Adds Capacitor VPN API implementation |
| client/web/app/main.cordova.ts | Uses pluginExec wrapper for quit flow |
| client/web/app/main.capacitor.ts | Adds Capacitor main entry: splash, browser, method channel, platform impl |
| client/web/app/browser.ts | Adds Capacitor in-app browser link interception |
| client/package.json | Adds Capacitor deps; updates clean script; removes old Husky |
| client/capacitor/www/manifest.json | Adds Capacitor web manifest (icons) |
| client/capacitor/www/mainfest.json | Adds duplicate manifest file with misspelled name |
| client/capacitor/webpack.config.js | Adds local webpack config (Capacitor package) |
| client/capacitor/tsconfig.json | Adds TS config for Capacitor package tooling |
| client/capacitor/start.action.mjs | Adds dev-server/hot-reload action that patches Capacitor config |
| client/capacitor/src/index.js | Adds sample entry file (device info) |
| client/capacitor/plugins/capacitor-plugin-outline/tsconfig.json | Adds TS config for Capacitor Outline plugin |
| client/capacitor/plugins/capacitor-plugin-outline/src/web.ts | Adds web stub implementation for Capacitor plugin |
| client/capacitor/plugins/capacitor-plugin-outline/src/index.ts | Registers Capacitor plugin entrypoint |
| client/capacitor/plugins/capacitor-plugin-outline/src/definitions.ts | Adds TypeScript definitions for plugin API |
| client/capacitor/plugins/capacitor-plugin-outline/package.json | Adds plugin package metadata/build script |
| client/capacitor/plugins/capacitor-plugin-outline/ios/Sources/CapacitorPluginOutline/CapacitorPluginOutlineImplementation.swift | Adds iOS native implementation for VPN/error reporting |
| client/capacitor/plugins/capacitor-plugin-outline/ios/Sources/CapacitorPluginOutline/CapacitorPluginOutline.swift | Adds Capacitor bridged plugin wrapper |
| client/capacitor/plugins/capacitor-plugin-outline/ios/Package.swift | Adds SwiftPM package for iOS plugin |
| client/capacitor/plugins/capacitor-plugin-outline/android/src/main/res/values/bypass_subnets.xml | Adds Android resource reference (currently not valid XML content) |
| client/capacitor/plugins/capacitor-plugin-outline/android/src/main/java/org/outline/CapacitorPluginOutline.kt | Adds Android native plugin implementation |
| client/capacitor/plugins/capacitor-plugin-outline/android/build.gradle | Adds Android library build for plugin |
| client/capacitor/package.json | Adds Capacitor app package + sync scripts |
| client/capacitor/ios/debug.xcconfig | Adds placeholder xcconfig |
| client/capacitor/ios/App/VpnExtension/VpnExtension.entitlements | Adds VpnExtension entitlements link/reference |
| client/capacitor/ios/App/VpnExtension/Sources | Adds VpnExtension sources link/reference |
| client/capacitor/ios/App/VpnExtension/Info.plist | Adds VpnExtension Info.plist link/reference |
| client/capacitor/ios/App/CapApp-SPM/Sources/CapApp-SPM/Empty.swift | Adds SwiftPM placeholder source |
| client/capacitor/ios/App/CapApp-SPM/Package.swift | Adds pinned SwiftPM dependencies for Capacitor iOS app |
| client/capacitor/ios/App/App/OutlineViewController.swift | Adds custom bridge view controller + debugging helpers |
| client/capacitor/ios/App/App/Info.plist | Adds iOS app Info.plist for Capacitor target |
| client/capacitor/ios/App/App/Base.lproj/LaunchScreen.storyboard | Adds iOS launch screen storyboard |
| client/capacitor/ios/App/App/Assets.xcassets/Splash.imageset/Contents.json | Adds splash asset catalog metadata |
| client/capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json | Adds app icon asset catalog metadata |
| client/capacitor/ios/App/App/AppDelegate.swift | Adds iOS app delegate with webview recovery + URL handling |
| client/capacitor/ios/App/App/App.entitlements | Adds iOS app entitlements for VPN/app groups |
| client/capacitor/ios/App/App.xcodeproj/xcshareddata/xcschemes/VpnExtension.xcscheme | Adds shared scheme for VPN extension |
| client/capacitor/ios/App/App.xcodeproj/xcshareddata/xcschemes/Outline.xcscheme | Adds shared scheme for app |
| client/capacitor/ios/App/App.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved | Adds SwiftPM resolved pins |
| client/capacitor/ios/App/App.xcodeproj/project.pbxproj | Adds Xcode project wiring for app + extension |
| client/capacitor/ios/.gitignore | Adds iOS project ignores for generated artifacts |
| client/capacitor/capacitor.config.json | Adds Capacitor config (splash/server/ios settings) |
| client/capacitor/build/templates/ios/CapApp-SPM.Package.swift.template | Adds template used to restore overwritten SwiftPM config |
| client/capacitor/build/templates/android/settings.gradle.template | Adds template used to restore Android settings.gradle |
| client/capacitor/build/templates/android/capacitor.build.gradle.template | Adds template used to restore capacitor.build.gradle |
| client/capacitor/build/cap-sync-ios.mjs | Adds wrapper to sync iOS + reapply templates + resize splash images |
| client/capacitor/build/cap-sync-android.mjs | Adds wrapper to sync Android + reapply templates |
| client/capacitor/build.action.mjs | Adds Capacitor build action for iOS/Android (debug/release) |
| client/capacitor/android/variables.gradle | Adds Android build variables/versions |
| client/capacitor/android/settings.gradle | Adds Android settings.gradle (template-based) |
| client/capacitor/android/gradlew.bat | Adds Windows Gradle wrapper script |
| client/capacitor/android/gradlew | Adds POSIX Gradle wrapper script |
| client/capacitor/android/gradle/wrapper/gradle-wrapper.properties | Pins Gradle distribution |
| client/capacitor/android/gradle.properties | Adds Gradle properties |
| client/capacitor/android/capacitor.settings.gradle | Adds Capacitor-generated module includes |
| client/capacitor/android/build.gradle | Adds Android top-level build config (template-based) |
| client/capacitor/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java | Adds example unit test (currently mismatched package) |
| client/capacitor/android/app/src/main/res/xml/file_paths.xml | Adds FileProvider paths |
| client/capacitor/android/app/src/main/res/values/styles.xml | Adds Android styles (theme/splash theme) |
| client/capacitor/android/app/src/main/res/values/strings.xml | Adds Android string resources |
| client/capacitor/android/app/src/main/res/values/ic_launcher_background.xml | Adds launcher background color |
| client/capacitor/android/app/src/main/res/layout/activity_main.xml | Adds main activity layout |
| client/capacitor/android/app/src/main/java/org/outline/client/MainActivity.java | Adds Capacitor BridgeActivity |
| client/capacitor/android/app/src/main/AndroidManifest.xml | Adds Android manifest with VPN service + receiver wiring |
| client/capacitor/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java | Adds example instrumented test (assert currently incorrect) |
| client/capacitor/android/app/proguard-rules.pro | Adds ProGuard rules file |
| client/capacitor/android/app/capacitor.build.gradle | Adds capacitor.build.gradle (template-based) |
| client/capacitor/android/app/build.gradle | Adds app build.gradle with Outline deps + Java 17 config |
| client/capacitor/android/app/.gitignore | Adds ignore rules for Android app build dir |
| client/capacitor/android/.gitignore | Adds Android project ignores |
| client/capacitor/README.md | Adds developer instructions for Capacitor builds |
| client/build/get_build_parameters.mjs | Adds Capacitor platforms to allowed build parameters |
| client/.gitignore | Expands ignores (IDE, node_modules, outputs, icons) |
| .gitignore | Ignores generated Capacitor icon/splash assets and plugin build outputs |
Comments suppressed due to low confidence (5)
client/capacitor/www/mainfest.json:1
- This file appears to be a duplicate of
manifest.jsonwith a misspelled filename (mainfest.json). Keeping both risks shipping or referencing the wrong manifest; remove this file or rename it tomanifest.jsonand ensure only one source of truth is referenced.
client/capacitor/www/manifest.json:1 - The manifest icon
srcuses.webpfiles, but the declared MIMEtypeisimage/png. This mismatch can cause the icons to be ignored by user agents. Update thetypetoimage/webp(preferred) or switch the icon files to.pngto match the declared type.
client/web/app/plugin.capacitor.ts:1 - The
default:case declaresconstvariables without wrapping the case body in braces. In TS/JS, lexical declarations inswitchcases must be scoped (e.g.,default: { ... }) to avoid compile errors and/or case-leakage. Wrap thedefaultbody in a block and ensure the control flow exits the switch cleanly.
client/web/app/plugin.capacitor.ts:1 - This import reaches into another package’s
src/path, which couples the web app to that package’s internal layout and bypasses its published entrypoints/build output. Prefer importing from the plugin package entry (e.g., the package name) or a stable, exported module path so refactors/build output changes won’t break consumers.
client/capacitor/plugins/capacitor-plugin-outline/android/src/main/res/values/bypass_subnets.xml:1 - This file is not valid Android XML resource content; AAPT will fail to parse it if it’s treated as a normal resource file. If the intent is to reference a shared resource via symlink, ensure it is committed as an actual symlink (mode 120000) in git; otherwise copy/generate the real XML into this path as part of the build.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| sourceCompatibility JavaVersion.VERSION_21 | ||
| targetCompatibility JavaVersion.VERSION_21 |
There was a problem hiding this comment.
We should probably use Java 21, not 17.
| // Context of the app under test. | ||
| Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); | ||
|
|
||
| assertEquals("com.getcapacitor.app", appContext.getPackageName()); |
client/capacitor/README.md
Outdated
|
|
||
| ## Requirements for all builds | ||
|
|
||
| All builds require [Node](https://nodejs.org/) 22 (lts/hydrogen), JDK 17 and [Go](https://golang.org/) 1.25 installed in addition to other per-platform requirements. |
package.json
Outdated
| "eslint-plugin-prettier": "^5.2.1", | ||
| "eslint-plugin-storybook": "^0.8.0", | ||
| "gts": "^5.3.1", | ||
| "husky": "^9.1.7", |
There was a problem hiding this comment.
If it's not being used, please don't add. No dead code.
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
| // | ||
| // Outline template for ios/App/CapApp-SPM/Package.swift. |
There was a problem hiding this comment.
This package shouldn't be needed. We can edit the app project directly, and add the Swift dependencies to the XC workspace.
There was a problem hiding this comment.
No — that package is wired into the iOS Xcode project as a local Swift package dependency. The project references CapApp-SPM explicitly, so removing Package.swift would break the workspace unless we also rewrite the Xcode project and maintain those dependencies manually after any Capacitor update.
There was a problem hiding this comment.
We shouldn't need this if we are putting the dependencies in the right place.
There was a problem hiding this comment.
Same here, we shouldn't need this because we can edit the XC workspace directly.
* fix: feedback implemented * updated capacitor build script with npx cap copy and removed scripts * Updates to readme and package --------- Co-authored-by: Muhammad Asad <asad@kodxsystem.com> Co-authored-by: Hasnainhanifse <hasnaindev786@gmail.com>
No description provided.