# GMPlayer Handoff Notes

## Current Project State

GMPlayer is a native mobile app workspace for collecting internet video URLs and playing them directly. The project currently has:

- iOS app in Swift + UIKit.
- Android app in Kotlin + Jetpack Compose.
- Shared requirements in `docs/requirements.md`.
- Design/exported player button assets in `design-assets/player-buttons`.

The root directory is not currently a Git repository in this environment, so use file inspection rather than Git history for handoff context.

## Product Flow

Current main flow:

1. User enters an `http` or `https` video URL.
2. URL must end with `.m3u8` or `.mp4`.
3. Valid URLs are added to a local in-memory history list, newest first, max 3 items.
4. Tapping play/add opens a full-screen player view.

## iOS Status

Main files:

- `ios/GMPlayer/PlayerViewController.swift`
  - Main URL input and history screen.
  - Validates `.m3u8` and `.mp4`.
  - Presents `VideoPlayerViewController(url:)`.

- `ios/GMPlayer/VideoPlayerViewController.swift`
  - Full-screen custom player based on `AVPlayer` and `AVPlayerLayer`.
  - Uses custom controls, not `AVPlayerViewController`.
  - Plays automatically on appear.
  - Supports close, play/pause/replay, seek backward/forward 15 seconds, progress display, and drag-to-seek.
  - Control overlay behavior:
    - Tap empty video area to show/hide controls.
    - When visible, controls auto-hide after 4 seconds without interaction.
    - Show/hide uses fade animation.
    - Playback buttons and progress dragging reset the auto-hide timer.

- `ios/GMPlayer/MobilePlaybackControlsView.swift`
  - Center control group.
  - Supports side controls mode:
    - `.skip15`
    - `.playlist`
    - `.hidden`

- `ios/GMPlayer/PlayerControlsConfiguration.swift`
  - Current side button mode is configured here.

- `ios/GMPlayer/MobileProgressBarInfoView.swift`
  - Bottom title/time/progress area.
  - Height expected to be 106.
  - Progress bar supports horizontal scrubbing.

- `ios/GMPlayer/MobileMainControllerButton.swift`
- `ios/GMPlayer/MobileSkipButton.swift`
  - Custom button rendering using exported PNG resources.
  - Circular background uses `UIVisualEffectView` with `.systemUltraThinMaterialDark`.
  - No additional black overlay on iOS.

Temporary native system player testing was removed. There should be no `SystemVideoPlayerViewController.swift`.

### iOS Assets

Player button assets live in:

- `ios/GMPlayer/Assets.xcassets/player_button_play.imageset`
- `ios/GMPlayer/Assets.xcassets/player_button_pause.imageset`
- `ios/GMPlayer/Assets.xcassets/player_button_replay.imageset`
- `ios/GMPlayer/Assets.xcassets/player_button_go_backwards_15.imageset`
- `ios/GMPlayer/Assets.xcassets/player_button_go_forward_15.imageset`
- `ios/GMPlayer/Assets.xcassets/player_button_skip_backward.imageset`
- `ios/GMPlayer/Assets.xcassets/player_button_skip_forward.imageset`

App icon assets are in:

- `ios/GMPlayer/Assets.xcassets/AppIcon.appiconset`

### iOS Build And Run

Known working simulator:

- iPhone 17
- iOS 26.5
- UDID: `68D65FB5-95B9-4E38-8552-2A1934459005`

Build:

```sh
xcodebuild -project ios/GMPlayer.xcodeproj -scheme GMPlayer -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.5' build
```

Install and launch:

```sh
open -a Simulator
xcrun simctl boot 68D65FB5-95B9-4E38-8552-2A1934459005
xcrun simctl install 68D65FB5-95B9-4E38-8552-2A1934459005 /Users/flyzto/Library/Developer/Xcode/DerivedData/GMPlayer-bikaarnrdbqjvfbzwmpbnythjtrj/Build/Products/Debug-iphonesimulator/GMPlayer.app
xcrun simctl launch 68D65FB5-95B9-4E38-8552-2A1934459005 com.gmplayer.app
```

Last verified iOS run:

- Date: 2026-06-10
- Build succeeded.
- Installed and launched on iPhone 17 / iOS 26.5.

Known warning:

- `PlayerViewController.swift` uses deprecated `UIButton.contentEdgeInsets`; currently harmless for this scaffold.

## Android Status

Main files:

- `android/app/src/main/java/com/gmplayer/app/MainActivity.kt`
  - Main URL input and history screen.
  - Opens `AndroidPlayerScreen` after a valid URL is added.
  - `AndroidPlayerScreen` uses Android `VideoView` with Compose overlays.
  - Control overlay behavior is synchronized with iOS intent:
    - Tap video area to show/hide controls.
    - Auto-hide after 4 seconds when visible.
    - Fade in/out animation is 220ms.
    - Button interactions reset the timer.
    - Android back exits the player screen.

- `android/app/src/main/java/com/gmplayer/app/MobilePlaybackControls.kt`
  - Center control group.
  - Supports side controls mode:
    - `Skip15`
    - `Playlist`
    - `Hidden`
  - Android button backgrounds include a 25% black circular layer so transparent exported icons remain visible.

- `android/app/src/main/java/com/gmplayer/app/MobileMainControllerButton.kt`
- `android/app/src/main/java/com/gmplayer/app/MobileProgressBarInfo.kt`
- `android/app/src/main/java/com/gmplayer/app/PlayerControlsConfiguration.kt`

### Android Assets

Button resources were copied from `design-assets/player-buttons` into Android resource folders. Current button names include:

- `player_button_play`
- `player_button_pause`
- `player_button_replay`
- `player_button_go_backwards_15`
- `player_button_go_forward_15`
- `player_button_skip_backward`
- `player_button_skip_forward`

### Android Build Notes

This environment currently does not have:

- `android/gradlew`
- global `gradle`

So Android has not been compiled locally after the latest player overlay changes. Open `android/` in Android Studio or add/sync a Gradle wrapper before verifying:

```sh
cd android
./gradlew :app:assembleDebug
```

## Player UX Details

iOS currently has the most complete custom player implementation:

- Custom full-screen player.
- Center play/pause/replay and side controls.
- Bottom progress info area.
- Drag-to-seek.
- Auto-hide controls.
- Fade transitions.

Android has the matching overlay behavior at the Compose level, but playback is currently implemented with `VideoView`. If parity matters for HLS behavior and richer controls, consider moving Android playback to Media3 ExoPlayer.

## Design/Figma Context

The player UI was based on the Figma file:

- `Video Player For Web Mobile Community`
- File key: `ApvSwPRpW7jYhJ0xUohpT4`

Relevant Figma nodes previously inspected/used:

- Mobile Player node: `21:4432`
- Play button states: `40:99`

The user exported button PNGs at `@1x`, `@2x`, and `@3x`. Figma default `@1x` export has no suffix; these were mapped into iOS imagesets and Android drawable resources.

## Important Decisions Already Made

- The app should use native projects for iOS and Android.
- React component generation is not needed.
- iOS should use the custom player, not `AVPlayerViewController`, for the product direction.
- Main page should not embed a player placeholder.
- Clicking play/add should open a full-screen player.
- Player should not show subtitle.
- iOS control button blur uses `.systemUltraThinMaterialDark`.
- Android uses a 25% black circular background behind transparent button icons for now.
- Side controls should show only one set:
  - 15-second seek controls, or
  - previous/next controls, or
  - no side controls.

## Known Gaps / Next Steps

- Android build needs Gradle wrapper or Android Studio sync.
- Android playback should likely be upgraded from `VideoView` to Media3 ExoPlayer for robust `.m3u8` and `.mp4` parity.
- Android progress info is currently static in the overlay and should be wired to playback position/duration.
- Android drag-to-seek is not yet implemented.
- iOS AirPlay, playback speed, mute, and full-screen controls were discussed earlier, but the current restored custom player only has the implemented subset described above.
- History is in-memory only on both platforms; persistence has not been added.
- No automated tests are currently present.

## Suggested Next Implementation Order

1. Verify Android project in Android Studio or add `gradlew`.
2. Replace Android `VideoView` with Media3 ExoPlayer.
3. Wire Android progress, duration, and drag-to-seek.
4. Add persistent history storage on both platforms.
5. Add player speed, mute, full-screen/orientation behavior, and AirPlay where required.
6. Add focused unit/UI tests for URL validation and player state transitions.
