# Schnappix Schnappix is a tablet-optimized Photobooth application built with React Native and Expo. It provides a full-featured, interactive photo capturing experience, complete with external hardware support, image editing, and an administrative interface. ## Features - **Photobooth Experience**: Intuitive flow from start screen to countdown, photo capture, and final preview. - **Multiple Photos & Collages**: Capture single or multiple photos and review them in a generated collage. - **Sticker / Emoji Editor**: Add emojis, date/time stamps, and event text as draggable, resizable, rotatable stickers on your photos — just like on social media. - **Photo Frames**: Overlay transparent PNG frames on photos. Admin can set frames to off, always-on, or user-selectable. - **Continuous Shooting (Burst Mode)**: Automatically capture multiple photos in sequence (2–5 shots, configurable interval) for collage printing. - **Date/Time Overlay**: Optionally stamp the date and/or time on every photo, with configurable position. - **Camera Flash Effect**: Full-screen white flash animation on every capture for an authentic photo booth feel. - **Direct Printing**: Built-in support for IPP (Internet Printing Protocol) network printers to instantly print captured moments. - **Kiosk Mode**: Custom native Android implementation to lock the tablet down to the Schnappix app, preventing users from exiting the photobooth. - **USB Camera Support**: Extends standard camera capabilities to support external USB cameras for higher quality photos. - **Admin Dashboard**: Secure administrative screen (protected by an admin password) to configure all settings on the fly. - **Offline Storage**: Saves captured photos directly to the device's local storage and gallery. ## Tech Stack - **Framework**: [React Native](https://reactnative.dev/) (v0.81.5) & [Expo](https://expo.dev/) (SDK 54) - **Language**: TypeScript - **Key Libraries**: - `expo-camera`: Camera interface - `expo-media-library` & `expo-file-system`: Photo storage - `ipp-encoder`: Network printing integration - `react-native-view-shot`: Capturing collages as images - `react-native-gesture-handler`: Sticker drag, pinch, and rotate gestures - `@fortawesome/react-native-fontawesome`: All in-app icons via Font Awesome - `react-native-svg`: SVG rendering for icon support - Custom native Expo plugins (`withKioskAdmin`, `withUsbCamera`, `withSettingsRepositories`) for extended Android capabilities. ## Getting Started ### Prerequisites - Node.js (v18+) - npm or yarn - Expo CLI - Android Studio / Android SDK (for building the native Android app, as it uses custom native modules) ### Installation 1. Clone the repository: ```bash git clone cd Schnappix ``` 2. Install dependencies: ```bash npm install ``` 3. Prebuild the native Android project (required due to custom native plugins): ```bash npx expo prebuild --clean --platform android ``` 4. Run the app on an Android device or emulator: ```bash npm run android ``` ## Project Structure ```text Schnappix/ ├── App.tsx # Main entry point, navigation, GestureHandlerRootView ├── Icon.png # App icon (neon synthwave photo booth) ├── app.json # Expo configuration and plugin registration ├── assets/ │ └── frames/ # Photo frame PNG overlays (user-provided) ├── plugins/ # Custom Expo config plugins for Android features ├── modules/ # Custom native modules (kiosk-mode, usb-camera) └── src/ ├── components/ # Reusable UI components │ ├── Icon.tsx # Font Awesome icon wrapper │ ├── DraggableSticker.tsx # Gesture-based sticker (pan, pinch, rotate) │ ├── StickerTray.tsx # Emoji/sticker picker tray │ ├── FrameOverlay.tsx # Frame PNG overlay renderer │ └── FramePicker.tsx # Frame selection UI ├── data/ │ └── frames.ts # Frame asset registry ├── screens/ # UI Screens (Camera, Preview, Admin) ├── services/ # Core logic (printer.ts, settings.ts, storage.ts) └── styles/ # Global theme (neon synthwave palette) ``` ## Configuration When the app is first launched, you can access the **Admin Dashboard** by tapping the settings icon (⚙️) on the Home screen and entering the admin password (default: `1234`). ### Admin Settings Overview | Setting | Description | Default | |---|---|---| | **Drucker IP-Adresse** | Local IP of the Canon CP1300 printer | `192.168.1.100` | | **Countdown-Dauer** | Seconds before photo capture | `3` | | **Admin-Passwort** | PIN to access admin panel | `1234` | | **Begrüßungstext** | Welcome text on the home screen | `Willkommen zu unserer Feier!` | | **Event-Name** | Event text for the date sticker (e.g. `Jannik's Party`) | _(empty)_ | | **Serienbild-Anzahl** | Number of photos per burst (1 = single shot) | `1` | | **Serienbild-Abstand** | Seconds between burst shots | `5` | | **Fotorahmen-Modus** | `Aus` / `Immer an` / `Verfügbar` | `Aus` | | **Datum-Einblendung** | `Aus` / `Nur Datum` / `Datum + Uhrzeit` | `Aus` | | **Datum-Position** | Placement of the auto date stamp | `Unten rechts` | | **Kiosk-Modus** | Lock the tablet to the Schnappix app | `Aus` | --- ## Kiosk Mode (Device Owner) Setup To use the **true Kiosk Mode** (Lock Task Mode) without system confirmation prompts, the Schnappix app must be set as the Android "Device Owner". This requires connecting the tablet to a PC via USB and using `adb`. **Prerequisites:** 1. The Android tablet must have no other accounts (like a Google Account) configured. It is highly recommended to start with a factory-reset device. 2. Developer Options and USB Debugging must be enabled on the tablet. 3. The Schnappix APK must be installed on the tablet. **Setup Command:** Run the following command in your terminal/command prompt while the tablet is connected: ```bash adb shell dpm set-device-owner de.orfel.schnappix/expo.modules.kioskmode.AdminReceiver ``` If successful, the terminal will output `Success: Device owner set to package de.orfel.schnappix`. You can now safely disconnect the tablet and toggle the Kiosk Mode in the app's Admin Dashboard. *Note: Once set as Device Owner, the app cannot be uninstalled normally. You must either factory reset the device or implement a programmatic way to remove the active admin status.* --- ## Photo Frames — Setup Guide Schnappix supports custom photo frame overlays. Frames are transparent PNG images that are layered on top of photos before saving or printing. ### Frame Requirements | Property | Requirement | |---|---| | **Format** | PNG with **alpha channel** (transparency) | | **Resolution** | **1500 × 1000 px** (3:2 landscape ratio, matches landscape tablet display and print output) | | **Color mode** | sRGB, 8-bit | | **Transparency** | The photo area **must be fully transparent** (alpha = 0) | | **Safe zone** | Keep transparent "window" at least **60 px** inset from edges | | **File size** | Keep each file under **500 KB** for fast rendering | | **Naming** | `frame_.png` (e.g. `frame_balloons.png`, `frame_neon.png`) | ### Frame Layout Example ``` ┌──────────────────────────┐ │ 🎈🎈 🎈🎈 │ ← Decorative artwork (opaque pixels) │ │ │ ┌──────────────────┐ │ │ │ │ │ │ │ TRANSPARENT │ │ ← Photo shows through here (alpha = 0) │ │ (alpha=0) │ │ │ │ │ │ │ └──────────────────┘ │ │ │ │ ★ EVENT NAME ★ │ ← Bottom text / artwork (opaque pixels) └──────────────────────────┘ 1500 × 1000 px ``` ### How to Add Frames 1. **Create your frame PNG** according to the specifications above. Use any image editor (Photoshop, GIMP, Figma, Canva) that supports transparency export. 2. **Place the file** in the `assets/frames/` directory: ``` assets/frames/frame_balloons.png assets/frames/frame_party_name.png assets/frames/frame_neon.png ``` 3. **Register the frame** in `src/data/frames.ts`: ```typescript export const FRAMES: FrameDefinition[] = [ { id: 'balloons', name: 'Luftballons', asset: require('../../assets/frames/frame_balloons.png') }, { id: 'party_name', name: 'Party Name', asset: require('../../assets/frames/frame_party_name.png') }, { id: 'neon', name: 'Neon Glow', asset: require('../../assets/frames/frame_neon.png') }, ]; ``` 4. **Rebuild the app** (asset changes require a rebuild): ```bash npx expo prebuild --clean --platform android npm run android ``` 5. **Select the frame mode** in the Admin Dashboard: - **Aus** — No frames - **Immer an** — A specific frame is always applied (admin picks which one) - **Verfügbar** — Guests can choose a frame from the picker in the preview screen ### Tips for Designing Frames - **Test at print size**: The Canon CP1300 prints at 6×4 inches (roughly 1500×1000 px at 250+ DPI). Make sure your frame elements are sharp at this resolution. - **Leave enough transparent space**: Guests' faces should not be covered. Keep decorative elements on edges and corners. - **Use subtle borders**: A thin border or vignette effect around the transparent window helps frames look polished. - **Match the event**: Create themed frames for weddings, birthdays, corporate events, etc. --- ## Sticker Editing The preview screen includes a social-media-style sticker editor. Guests can: - **Add emojis**: Tap the "Sticker" button to open the emoji tray with 30 curated party emojis - **Drag** stickers anywhere on the photo - **Pinch to resize** stickers - **Two-finger rotate** stickers - **Tap to select**, then press × to delete - **Add date/time stickers**: Always available — tap "Datum" or "Datum + Uhrzeit" in the tray - **Add event sticker**: Shows event name + date (if configured in admin) All stickers are rendered inside the capture area, so they appear in the saved and printed output. --- ## Design Theme The app uses a **neon synthwave** aesthetic matching the app icon: - **Primary**: Electric magenta `#ff2bd6` - **Accent**: Cyan blue `#28dfff` - **Background**: Deep navy/black `#050510` - **Effects**: Neon glow shadows, glassmorphism overlays - **Icons**: Font Awesome (solid) with neon coloring ## License See the [LICENSE](LICENSE) file for more information.