Skip to content

feat(client): Added Capacitor Apps for iOS & Android#2723

Open
ayush-teon wants to merge 43 commits intoOutlineFoundation:masterfrom
nthlink:master
Open

feat(client): Added Capacitor Apps for iOS & Android#2723
ayush-teon wants to merge 43 commits intoOutlineFoundation:masterfrom
nthlink:master

Conversation

@ayush-teon
Copy link

No description provided.

ayush-teon and others added 30 commits July 15, 2025 20:53
* 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>
Zahirul Islam and others added 12 commits October 22, 2025 16:33
…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>
@ayush-teon ayush-teon requested a review from a team as a code owner March 10, 2026 19:46
@fortuna fortuna self-requested a review March 14, 2026 18:55
package.json Outdated
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-storybook": "^0.8.0",
"gts": "^5.3.1",
"husky": "^9.1.7",
Copy link
Collaborator

Choose a reason for hiding this comment

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

What is husky being used for?

Copy link
Author

Choose a reason for hiding this comment

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

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.

Copy link
Collaborator

Choose a reason for hiding this comment

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

If it's not being used, please don't add. No dead code.

Copy link
Author

Choose a reason for hiding this comment

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

Its has been removed now..




# Capacitor generated assets (icons, splash screens)
Copy link
Collaborator

Choose a reason for hiding this comment

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

What's the source for these?
Is there any actual transformation, or do we use the sources unmodified?

Choose a reason for hiding this comment

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

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
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we also generate this?

Choose a reason for hiding this comment

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

Yes, these are auto generated during build.

Copy link
Collaborator

Choose a reason for hiding this comment

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

When and how is this generated in the development workflow?

Choose a reason for hiding this comment

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

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');

@fortuna fortuna requested review from Copilot and fortuna March 14, 2026 18:56
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

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.json with a misspelled filename (mainfest.json). Keeping both risks shipping or referencing the wrong manifest; remove this file or rename it to manifest.json and ensure only one source of truth is referenced.
    client/capacitor/www/manifest.json:1
  • The manifest icon src uses .webp files, but the declared MIME type is image/png. This mismatch can cause the icons to be ignored by user agents. Update the type to image/webp (preferred) or switch the icon files to .png to match the declared type.
    client/web/app/plugin.capacitor.ts:1
  • The default: case declares const variables without wrapping the case body in braces. In TS/JS, lexical declarations in switch cases must be scoped (e.g., default: { ... }) to avoid compile errors and/or case-leakage. Wrap the default body 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.

Comment on lines +18 to +19
sourceCompatibility JavaVersion.VERSION_21
targetCompatibility JavaVersion.VERSION_21
Copy link
Collaborator

Choose a reason for hiding this comment

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

We should probably use Java 21, not 17.

Copy link
Author

Choose a reason for hiding this comment

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

Updated

// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();

assertEquals("com.getcapacitor.app", appContext.getPackageName());
Copy link
Author

Choose a reason for hiding this comment

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

Updated


## 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.
Copy link
Author

Choose a reason for hiding this comment

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

Updated

package.json Outdated
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-storybook": "^0.8.0",
"gts": "^5.3.1",
"husky": "^9.1.7",
Copy link
Collaborator

Choose a reason for hiding this comment

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

If it's not being used, please don't add. No dead code.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Remove the example files

Copy link
Author

Choose a reason for hiding this comment

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

Removed

Copy link
Collaborator

Choose a reason for hiding this comment

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

Remove the example files

Copy link
Author

Choose a reason for hiding this comment

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

Removed

// See the License for the specific language governing permissions and
// limitations under the License.
//
// Outline template for ios/App/CapApp-SPM/Package.swift.
Copy link
Collaborator

Choose a reason for hiding this comment

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

This package shouldn't be needed. We can edit the app project directly, and add the Swift dependencies to the XC workspace.

Copy link
Author

Choose a reason for hiding this comment

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

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.

Copy link
Collaborator

Choose a reason for hiding this comment

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

We shouldn't need this if we are putting the dependencies in the right place.

Copy link
Author

Choose a reason for hiding this comment

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

Updated

Copy link
Collaborator

Choose a reason for hiding this comment

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

Same here, we shouldn't need this because we can edit the XC workspace directly.

Copy link
Author

Choose a reason for hiding this comment

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

Updated

@fortuna fortuna requested a review from jyyi1 March 17, 2026 03:48
* 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>
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.

6 participants