Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .browserslistrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
last 2 major versions
not dead
Safari >=16.1
iOS >=16.1
Chrome >=107
ChromeAndroid >=60
Firefox >=106
Edge >=107
125 changes: 125 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# WebNative App - AI Agent Instructions

## Project Overview
WebNative is a cross-platform web browser application (iOS/Android via Capacitor) built with Angular 21 and Ionic 8. It enables viewing websites, scanning QR codes, and discovering local services. Deployed to App/Play Stores and https://webnative.app.

## Architecture Essentials

### Tech Stack
- **Framework**: Angular 21 with Ionic 8 (standalone components)
- **Mobile**: Capacitor 7+ (replaces Cordova) for iOS/Android
- **Build**: Angular CLI with bun package manager
- **Testing**: Vitest with jsdom environment
- **Styling**: SCSS with Ionic theme variables

### Core Services Pattern
All services use Angular's `@Injectable({ providedIn: 'root' })` for tree-shakeable singletons:
- **HistoryService**: Manages URL history/shortcuts via Capacitor Preferences
- **ScanService**: QR/barcode scanning via Capacitor plugin
- **SettingsService**: UI presentation (ActionSheets) for settings/actions
- **UrlService**: Deep linking and URL navigation handling
- **UIService**: Toast/dialog notifications
- **UtilService**: Utility functions (strings, random IDs)

### Key Patterns
1. **Dependency Injection**: Use `inject()` helper in constructors, not constructor params (modern Angular pattern)
2. **Service Communication**: Direct service injection; use RxJS Observables when state changes propagate
3. **Cordova Plugin Access**: Wrapped in `cordova-plugins.ts` with typed interfaces (avoid direct window access)
4. **Capacitor vs Cordova**: Prefer Capacitor APIs; some plugins still use Cordova bridges (Http, BarcodeScanner)

## Build & Development Commands

```bash
bun install # Install dependencies
npm start # Local dev server (ng serve)
npm run build # Production build → www/browser/
npm run test:unit # Run Vitest in watch mode
npm run test:unit:run # Run tests once (CI)
npm run lint # ESLint check
npm run lint-fix # Auto-fix ESLint & Prettier
npm run deploy # Build + deploy to Netlify
npm run packages # Generate plugin list for README
npm run capacitor:sync:after # Post-sync patches for Capacitor bridge issues
```

**Critical**: After `capacitor sync`, run `npm run capacitor:sync:after` to apply custom patches to CAPLog.swift and Logger.java (see `patch/` directory).

## Routing & Navigation

Routes use standalone component lazy-loading in [src/app/app-routes.ts](../src/app/app-routes.ts):
- `/home` → HomePage (main UI)
- `/privacy` → PrivacyPage (legal)
- `/capacitor` → CapacitorPage (dev/fallback for first-time users)
- Deep links via `App.addListener('appUrlOpen')` → `UrlService.deepLink()`

## Native Features Integration

### Capacitor Plugins Used
- **Filesystem**: File I/O for shortcuts/icons
- **Preferences**: Local storage (replaces localStorage for plugins)
- **Browser**: Open URLs in system browser
- **App**: Version info, deep links
- **StatusBar/Keyboard**: UI chrome control
- **Barcode Scanner**: QR code scanning (via Cordova bridge)
- **Screen Orientation**: Lock to portrait/landscape

### Discovery Service
Local device discovery via `IonicDiscover` (custom Cordova plugin) finds mDNS services. [src/app/discovery.ts](../src/app/discovery.ts) defines Service interface with name, hostname, address, port fields.

## File Organization

```
src/app/
├── [service-name].service.ts # Shared services
├── [service-name].service.spec.ts # Unit tests
├── home/ # Main page (lazy-loaded)
├── slides/ # Tutorial components
├── shortcut/ # Shortcut UI component
├── capacitor/ # Dev/fallback page
├── privacy/ # Legal page
└── cordova-plugins.ts # Plugin type definitions
```

## Testing & Linting

- **Unit Tests**: Vitest with jsdom, included in `src/**/*.spec.ts`
- **Config**: [vitest.config.ts](../vitest.config.ts) with path alias `@/` → `src/`
- **Linting**: @ionic/eslint-config with Prettier auto-formatting
- **Run Tests**: `npm run test:unit:ui` for interactive testing dashboard

## Capacitor Configuration

[capacitor.config.ts](../capacitor.config.ts) key settings:
- **webDir**: `www/browser` (production build output)
- **allowNavigation**: `['*']` (allow all URLs in web view)
- **cleartext**: `true` (allows HTTP on Android)
- **errorPath**: `error.html` (fallback for missing pages)
- **CapacitorHttp**: Disabled (uses Cordova advanced-http plugin instead)

## Common Workflows

### Adding a New Service
1. Create `src/app/[name].service.ts` with `@Injectable({ providedIn: 'root' })`
2. Inject via `inject()` in components
3. Add unit test `[name].service.spec.ts`
4. Export from service barrel or import directly

### Modifying Capacitor Bridge
- Edit `patch/CAPLog.swift` or `patch/Logger.java`
- Run `npm run capacitor:sync:after` after `capacitor sync`
- Never commit node_modules changes directly

### Building for Mobile
```bash
bun install && npm run build # Web build
npx capacitor sync # Sync to iOS/Android
npm run capacitor:sync:after # Apply patches
# Then use Xcode/Android Studio to build signed releases
```

## Important Notes
- **Strict TypeScript**: `strict: true` in tsconfig.json; no implicit any
- **Angular Version**: Latest (21+) with latest Ionic standalone API
- **No jQuery/Legacy Cordova**: Use Capacitor, not legacy Cordova patterns
- **Tree Shaking**: Ensure all services use `providedIn: 'root'` for optimization
- **iOS/Android Keys**: Stored in `keys/AndroidKeys`; iOS signing via Xcode
5 changes: 5 additions & 0 deletions .github/workflows/app-android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ jobs:
distribution: 'zulu'
java-version: '21'

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'

- name: Install bun
uses: oven-sh/setup-bun@v1

Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/app-ios.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:

jobs:
build:
runs-on: macos-15
runs-on: macos-26
name: Build iOS app
steps:
- name: Checkout source
Expand Down Expand Up @@ -46,7 +46,7 @@ jobs:
- name: Set up XCode
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: 16.4
xcode-version: 26.2.0

#- name: Setup Node.js
# uses: actions/setup-node@v4
Expand All @@ -71,7 +71,7 @@ jobs:
agvtool new-version -all ${{ github.run_id }}

- name: Select Xcode Version
run: sudo xcode-select -s /Applications/Xcode_16.4.app/Contents/Developer
run: sudo xcode-select -s /Applications/Xcode_26.2.app/Contents/Developer

- name: Build project
run: xcodebuild -workspace './ios/App/App.xcworkspace' -scheme App -destination generic/platform=iOS -archivePath App.xcarchive archive
Expand Down
79 changes: 33 additions & 46 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,57 +14,43 @@ Run all your standard Capacitor CLI commands to build and run on iOS and Android
The following plugins are preinstalled
<!--- Generated Plugins -->
- **@capacitor-community/apple-sign-in** - 7.1.0
- **@capacitor-community/bluetooth-le** - 7.2.0
- **@capacitor-community/camera-preview** - 7.0.2
- **@capacitor-community/keep-awake** - 7.1.0
- **@capacitor/action-sheet** - 7.0.2
- **@capacitor/app** - 7.1.0
- **@capacitor/barcode-scanner** - 2.2.0
- **@capacitor/browser** - 7.0.2
- **@capacitor/camera** - 7.0.2
- **@capacitor/clipboard** - 7.0.2
- **@capacitor/device** - 7.0.2
- **@capacitor/dialog** - 7.0.2
- **@capacitor/file-viewer** - 1.0.5
- **@capacitor/filesystem** - 7.1.4
- **@capacitor/geolocation** - 7.1.5
- **@capacitor/haptics** - 7.0.2
- **@capacitor/inappbrowser** - 2.5.1
- **@capacitor/keyboard** - 7.0.3
- **@capacitor/local-notifications** - 7.0.3
- **@capacitor/motion** - 7.0.1
- **@capacitor/network** - 7.0.2
- **@capacitor/preferences** - 7.0.2
- **@capacitor/screen-orientation** - 7.0.2
- **@capacitor/screen-reader** - 7.0.2
- **@capacitor/share** - 7.0.2
- **@capacitor/splash-screen** - 7.0.3
- **@capacitor/status-bar** - 7.0.3
- **@capacitor/text-zoom** - 7.0.2
- **@capacitor/toast** - 7.0.2
- **@capawesome/capacitor-file-picker** - 7.2.0
- **@jsonjoy.com/buffers** - 1.2.1
- **@jsonjoy.com/codegen** - 1.0.0
- **@jsonjoy.com/json-pointer** - 1.0.2
- **@capacitor-community/bluetooth-le** - 8.0.1
- **@capacitor-community/camera-preview** - 7.0.4
- **@capacitor-community/keep-awake** - 8.0.0
- **@capacitor/action-sheet** - 8.0.0
- **@capacitor/app** - 8.0.0
- **@capacitor/barcode-scanner** - 3.0.1
- **@capacitor/browser** - 8.0.0
- **@capacitor/camera** - 8.0.0
- **@capacitor/clipboard** - 8.0.0
- **@capacitor/device** - 8.0.0
- **@capacitor/dialog** - 8.0.0
- **@capacitor/file-viewer** - 2.0.0
- **@capacitor/filesystem** - 8.1.0
- **@capacitor/geolocation** - 8.0.0
- **@capacitor/haptics** - 8.0.0
- **@capacitor/inappbrowser** - 3.0.1
- **@capacitor/keyboard** - 8.0.0
- **@capacitor/local-notifications** - 8.0.0
- **@capacitor/motion** - 8.0.0
- **@capacitor/network** - 8.0.0
- **@capacitor/preferences** - 8.0.0
- **@capacitor/screen-orientation** - 8.0.0
- **@capacitor/screen-reader** - 8.0.0
- **@capacitor/share** - 8.0.0
- **@capacitor/splash-screen** - 8.0.0
- **@capacitor/status-bar** - 8.0.0
- **@capacitor/text-zoom** - 8.0.0
- **@capacitor/toast** - 8.0.0
- **@capawesome/capacitor-file-picker** - 8.0.1
- **@sentry/capacitor** - 2.4.1
- **@vitest/ui** - 4.0.8
- **@vitest/ui** - 4.0.18
- **@webnativellc/cordova-plugin-ionic-discover** - 1.0.5
- **bl** - 4.1.0
- **buffer** - 5.7.1
- **builtin-modules** - 3.3.0
- **clone** - 1.0.4
- **cordova-plugin-advanced-http** - 3.3.1
- **cordova-plugin-file** - 8.1.3
- **cordova-plugin-inappbrowser** - 6.0.0
- **defaults** - 1.0.4
- **generator-function** - 2.0.1
- **glob-to-regex.js** - 1.2.0
- **ieee754** - 1.2.1
- **is-builtin-module** - 3.2.1
- **jsdom** - 27.1.0
- **mimic-fn** - 2.1.0
- **vitest** - 4.0.8
- **wcwidth** - 1.0.1
- **jsdom** - 27.4.0
- **vitest** - 4.0.18
<!--- Generated Plugins End -->

## App Store
Expand Down Expand Up @@ -97,5 +83,6 @@ Available in the [Play Store](https://play.google.com/store/apps/details?id=com.






4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ android {
applicationId "com.nexusconcepts.nexus"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 44
versionName "1.35"
versionCode 45
versionName "1.36"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
manifestPlaceholders = [
'AUTH_URL_SCHEME': 'io.ionic.capview'
Expand Down
2 changes: 1 addition & 1 deletion android/variables.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
ext {
minSdkVersion = 26
compileSdkVersion = 35
compileSdkVersion = 36
targetSdkVersion = 35
androidxActivityVersion = '1.9.2'
androidxAppCompatVersion = '1.7.0'
Expand Down
Loading