# Expo Receive Android Intents

An Expo module that handles incoming Android intents for sharing text, images, and videos into the Bluesky app.

## What It Does

This module intercepts Android share intents (when a user shares content from another app to Bluesky) and converts them into deep links that the app can handle. It supports:

- **Text sharing** - Share plain text to compose a post
- **Image sharing** - Share single or multiple images (up to 4) to attach to a post
- **Video sharing** - Share a single video to attach to a post

The module operates entirely in native Android code and requires no JavaScript API calls. It automatically registers itself with Expo's module system and handles intents when the app is launched or receives new intents.

## Platform Support

- **Android**: Fully supported
- **iOS**: No-op (iOS handles share intents differently)
- **Web**: No-op

## How It Works

### Architecture

The module uses Expo's module lifecycle hooks to intercept Android intents at two key moments:

1. **OnCreate** - When the app is first launched from an intent
2. **OnNewIntent** - When the app receives a new intent while already running

### Intent Processing Flow

1. **Intent Reception**: Android sends an `ACTION_SEND` or `ACTION_SEND_MULTIPLE` intent
2. **Type Detection**: Module determines content type (text, image, or video)
3. **Content Processing**:
   - **Text**: URL-encodes the text
   - **Images**: Saves to app cache, extracts dimensions (limited to 4 images max)
   - **Video**: Copies to app cache with extension detection, extracts dimensions
4. **Deep Link Generation**: Creates a `bluesky://intent/compose` URL with encoded parameters
5. **App Launch**: Starts a new activity with the deep link, which is handled by `useIntentHandler`

### Deep Link Format

The module generates deep links in the following formats:

```
# Text only
bluesky://intent/compose?text=<encoded-text>

# Images (single or multiple)
bluesky://intent/compose?imageUris=<uri1>|<width>|<height>,<uri2>|<width>|<height>&text=<encoded-text>

# Video (single only)
bluesky://intent/compose?videoUri=<uri>|<width>|<height>&text=<encoded-text>
```

All URIs use the `file://` scheme pointing to files in the app's cache directory. Dimensions are included to avoid expensive measurement operations in JavaScript.

### Security Considerations

- Images and videos are copied to the app's private cache directory before being passed to the app
- The JavaScript handler (`useIntentHandler.ts`) validates image URIs with a regex to prevent external URLs
- Image URIs containing `http://` or `https://` are filtered out
- Multiple image sharing is limited to 4 images maximum

## Key Files

### Module Configuration

- **expo-module.config.json** - Declares the module and registers it with Expo (Android-only)

### Native Implementation

- **ExpoReceiveAndroidIntentsModule.kt** - Main module class with intent handling logic
  - `handleIntent()` - Routes intents based on type
  - `handleTextIntent()` - Processes text sharing
  - `handleAttachmentIntent()` - Processes single image/video
  - `handleAttachmentsIntent()` - Processes multiple images
  - `getImageInfo()` - Saves images to cache and extracts dimensions
  - `getVideoInfo()` - Extracts video dimensions using MediaMetadataRetriever

- **android/build.gradle** - Gradle build configuration
  - Version: 0.4.1
  - Requires: Kotlin, expo-modules-core
  - Compile SDK: 33, Min SDK: 21, Target SDK: 34

- **android/src/main/AndroidManifest.xml** - Empty manifest (intent filters configured in main app)

### JavaScript Integration

The deep links generated by this module are handled by:

- **src/lib/hooks/useIntentHandler.ts** - `useComposeIntent()` parses the deep link parameters and opens the composer with pre-populated content

## Installation

No manual installation is required. Gradle automatically includes this module during the Android build process. The module is auto-linked through Expo's module system.

## Configuration

Intent filters must be configured in the main app's `AndroidManifest.xml` to declare which MIME types the app accepts. The module itself has an empty manifest.

## Implementation Notes

### Android Version Compatibility

The module uses version-specific APIs for Android 13+ (API 33):
- `getParcelableExtra()` with type parameter on Android 13+
- Legacy `getParcelableExtra()` on older versions

### File Handling

- Temporary files are created using `File.createTempFile()` in the app's cache directory
- Image files use `.jpeg` extension and are compressed at 100% quality
- Video files preserve their original extension, defaulting to `.mp4` if none is detected

### Limitations

- Video sharing only supports a single video
- Multiple video sharing is not implemented
- Images are always converted to JPEG format
- Maximum of 4 images can be shared at once
