# Android Client

Native Android app that wraps the Navi web client in a WebView.

## Location

`android-client/` — standalone Android project (Kotlin, Gradle).

## Architecture

Single-activity app with two screens:

| Activity | Purpose |
|---|---|
| `SetupActivity` | First-launch screen — prompts for server URL, saves to SharedPreferences |
| `MainActivity` | Main screen — full-screen WebView loading the Navi web client |

Server URL is stored in SharedPreferences under key `server_url`. If absent on launch, `SetupActivity` is shown. If the WebView fails to load the main frame, the saved URL is cleared so the next launch prompts again.

## Build & Deploy

```bash
cd android-client

# Debug APK
./gradlew assembleDebug

# Install via adb (device connected via USB)
adb install -r app/build/outputs/apk/debug/app-debug.apk

# One-liner: build + install
./gradlew assembleDebug && adb install -r app/build/outputs/apk/debug/app-debug.apk
```

## WebView configuration

| Setting | Value | Reason |
|---|---|---|
| `javaScriptEnabled` | true | Required for the Vue app |
| `domStorageEnabled` | true | Session state, composables |
| `cacheMode` | `LOAD_NO_CACHE` | Always fetch fresh from server |
| `mixedContentMode` | `ALWAYS_ALLOW` | Local server may serve mixed content |
| `userAgentString` | `…original… NaviAndroid/1.0` | Platform detection in web client |

## External link handling

`shouldOverrideUrlLoading` intercepts navigation:
- Normal Navi app URLs on the configured server host → handled by WebView.
- API, iframe, and artifact preview loads without a user gesture → handled by WebView.
- External hosts → opened via `Intent.ACTION_VIEW` in the system browser.
- User-clicked same-host artifact/file URLs → opened via `Intent.ACTION_VIEW` in the system browser:
  - `/content-viewers/...`
  - `/sessions/{session_id}/files/{filename}`
  - URLs with `download=1`

This means inline preview cards still render inside the app, but when the user explicitly opens a preview, raw file, download link, or external URL, it leaves the app and opens in the user's browser.

## Platform detection in web client

The app appends `NaviAndroid/1.0` to the WebView's User-Agent. The web client can detect this:

```js
import { isAndroid } from '@/composables/usePlatform.js'

if (isAndroid) {
  // Android-specific behaviour
}
```

`usePlatform.js` is a single-line composable:
```js
export const isAndroid = navigator.userAgent.includes('NaviAndroid')
```

Use this for any future UI differences between the web client and the Android app (hiding elements, adjusting layout, etc.).

## Back navigation

Hardware back button navigates WebView history if available (`webView.canGoBack()`), otherwise falls through to the default Android behaviour (closes the activity).

## File / image picker

`WebChromeClient.onShowFileChooser` is implemented to support image attachment in chat:
- Requests `CAMERA` and `READ_MEDIA_IMAGES` / `READ_EXTERNAL_STORAGE` permissions at runtime
- Presents a chooser combining gallery picker and camera capture
- Camera photos are saved to `getExternalFilesDir(DIRECTORY_PICTURES)` via `FileProvider`
