# Android App

This guide covers building and contributing to the KayakNet Android app.

## Overview

The Android app provides:

* Full KayakNet connectivity
* Chat (rooms and DMs)
* Marketplace browsing
* Domain lookup
* Native Android experience

## Tech Stack

* **Language:** Kotlin
* **UI:** Jetpack Compose
* **Architecture:** MVVM
* **Networking:** Ktor HTTP client
* **Build:** Gradle

## Project Structure

```
android/
├── app/
│   ├── src/main/
│   │   ├── java/com/kayaknet/
│   │   │   ├── MainActivity.kt
│   │   │   ├── KayakNetApp.kt
│   │   │   ├── ui/
│   │   │   │   ├── screens/
│   │   │   │   │   ├── HomeScreen.kt
│   │   │   │   │   ├── ChatScreen.kt
│   │   │   │   │   ├── MarketScreen.kt
│   │   │   │   │   └── DomainsScreen.kt
│   │   │   │   └── theme/
│   │   │   │       └── Theme.kt
│   │   │   └── network/
│   │   │       └── KayakNetClient.kt
│   │   ├── res/
│   │   │   ├── drawable/
│   │   │   └── values/
│   │   └── AndroidManifest.xml
│   └── build.gradle.kts
├── build.gradle.kts
└── settings.gradle.kts
```

## Building

### Prerequisites

* Android Studio Hedgehog (2023.1.1) or later
* JDK 17
* Android SDK (API 34)

### Build Steps

```bash
# Clone repository
git clone https://github.com/KayakNet/KayakNet.git
cd KayakNet/android

# Build debug APK
./gradlew assembleDebug

# Output: app/build/outputs/apk/debug/app-debug.apk
```

### Build Release APK

```bash
# Create signing key (first time only)
keytool -genkey -v -keystore kayaknet.keystore \
  -alias kayaknet -keyalg RSA -keysize 2048 -validity 10000

# Build release
./gradlew assembleRelease

# Output: app/build/outputs/apk/release/app-release.apk
```

## GitHub Actions

Automated builds via GitHub Actions:

```yaml
# .github/workflows/android.yml
name: Build Android APK

on:
  push:
    branches: [main]
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Set up JDK 17
        uses: actions/setup-java@v4
        with:
          java-version: '17'
          distribution: 'temurin'
      - name: Build APK
        run: |
          cd android
          chmod +x gradlew
          ./gradlew assembleDebug
      - name: Upload APK
        uses: actions/upload-artifact@v4
        with:
          name: kayaknet-debug
          path: android/app/build/outputs/apk/debug/app-debug.apk
```

## Architecture

### Network Communication

The app communicates with the KayakNet backend via HTTP:

```kotlin
class KayakNetClient(private val baseUrl: String) {
    private val client = HttpClient(CIO) {
        install(ContentNegotiation) {
            json()
        }
    }
    
    suspend fun getChatRooms(): List<ChatRoom> {
        return client.get("$baseUrl/api/chat/rooms").body()
    }
    
    suspend fun sendMessage(room: String, content: String) {
        client.post("$baseUrl/api/chat/send") {
            setBody(FormDataContent(Parameters.build {
                append("room", room)
                append("content", content)
            }))
        }
    }
}
```

### Bootstrap Connection

```kotlin
val bootstrapUrl = "http://203.161.33.237:8080"
val client = KayakNetClient(bootstrapUrl)
```

### UI with Jetpack Compose

```kotlin
@Composable
fun ChatScreen(viewModel: ChatViewModel) {
    val messages by viewModel.messages.collectAsState()
    
    Column {
        LazyColumn(modifier = Modifier.weight(1f)) {
            items(messages) { msg ->
                MessageItem(msg)
            }
        }
        MessageInput(onSend = { viewModel.sendMessage(it) })
    }
}
```

## Features Implementation

### Chat

* Rooms list from `/api/chat/rooms`
* Messages from `/api/chat/history`
* Send via POST `/api/chat/send`
* Polling for updates (1s interval)

### Marketplace

* Listings from `/api/market/listings`
* Details from `/api/market/listing?id=X`
* Categories and search supported

### Domains

* Lookup via `/api/domains/lookup?domain=X`
* My domains from `/api/domains/mine`

## Testing

### Unit Tests

```bash
./gradlew test
```

### Instrumented Tests

```bash
./gradlew connectedAndroidTest
```

### Manual Testing

1. Install APK on device/emulator
2. Ensure KayakNet node is running
3. App should connect automatically

## Known Issues

### No Local Node

The Android app connects to the bootstrap node, not a local node. This means:

* Relies on bootstrap availability
* No local proxy mode
* Limited offline capability

### Future: Embedded Node

Planned: Embed Go node using gomobile:

```bash
gomobile bind -target=android ./pkg/mobile
```

## Contributing

### Code Style

* Kotlin conventions
* Compose best practices
* Clear naming
* Comments for complex logic

### Pull Requests

1. Fork repository
2. Create feature branch
3. Test on multiple devices
4. Submit PR with description

## Troubleshooting

### Build Fails

```bash
# Clean and rebuild
./gradlew clean
./gradlew assembleDebug
```

### Connection Issues

* Verify bootstrap is running
* Check internet connectivity
* Try with VPN if needed

### UI Issues

* Check Compose version compatibility
* Verify Material3 components
* Test on different screen sizes
