Skip to main content
Version: 1.0.0

Structure

Details on architecture, folders, main files, and asset management for the Mirror Android app.


Architectural overview​

  • Pattern: MVVM with a feature-first package layout.
  • UI: Jetpack Compose (with a few Fragments for VTO camera overlays).
  • Activities:
    • MainActivity – portrait/landscape journey, navigation, video screensaver.
    • VtoActivity – Mediapipe + CameraX + transparent WebView (React) renderer.
  • Local server: LocalWebServer (NanoHTTPD) serves the React bundle and exchanges pose updates.
  • Persistence: Realm Kotlin for offline cache (local file paths to downloaded assets).

Top-level layout​

app/
├─ manifests/
├─ kotlin+java/it.spaarkly.arshadesmirror/
│ ├─ components/ # Reusable Compose UI (e.g., AutoResizedText)
│ ├─ models/ # Domain models (Brand, Mirror, Occhiale, Modello, Tag, Taglia, DisplayModel)
│ ├─ realm/ # Realm helpers (e.g., BrandRealm)
│ ├─ screens/ # Feature screens (Compose) – see below
│ ├─ ui.theme/ # Compose theme (Color.kt, Theme.kt, Type.kt)
│ ├─ vto_activity/ # VTO Activity, Fragments & Views (camera, overlays)
│ ├─ utils/ # FaceLandmarkerHelper, OneEuroFilter, VSlider, etc.
│ ├─ LocalWebServer.kt # Embedded HTTP/WebSocket server
│ ├─ MainActivity.kt / MainViewModel.kt
│ ├─ VtoActivity.kt / VtoViewModel.kt / MyApp.kt
│
├─ assets/
│ └─ www/ # React app served locally (mediapipe/, models/, static/*)
│ ├─ static/ (glb, hdr, png, task files, index.html, manifest.json, etc.)
│
├─ res/ # Drawables, layouts (if any), values
└─ build.gradle.kts, libs.versions.toml, etc.

Core ViewModels​

  • MainViewModel

    • Orchestrates all network + database work: reads Mirror doc, resolves brands/content, downloads all assets (images, GLB, HDR, videos), writes local file paths to Realm, exposes progress/status, restores orientation & theme.
    • Provides lists for gender/frame/brand/glasses selectors and screensaver video paths.
  • VtoViewModel

    • Owns Mediapipe options & face-tracking state.
    • Bridges FaceLandmarkerHelper → app state → LocalWebServer, streaming pose/offset updates so the React overlay can reposition the glasses model in real time.

  • Entry

    • entry_screen/MirrorIdEntryScreen – submit Mirror ID; triggers full sync.
    • Screensaver – video player (portrait/landscape variants) with tap-to-start.
  • Portrait flow

    • gender_selector/GenderSelector
    • frame_selector/FrameSelector
    • brand_selector/BrandSelector, BrandView
    • glasses_selector/GlassesSelector
    • model_viewer/ModelViewer – 3D viewer (WebView React + Kotlin UI controls)
    • vto_screen/VtoScreen – route to VtoActivity
  • Landscape flow

    • From video → directly to VtoActivity with auto-advancing selection (10s per item).
  • Global

    • language_selector/LanguageSelector – accessible from any page.
    • main/MainScreen – hosts the NavHost, inactivity wrapper, and bottom “Powered by ARShades” + T&C QR dialog.

VTO activity surface​

  • Fragments:

    • CameraFragment – CameraX feed.
    • ModelFragment / ModelFragmentPortrait – transparent WebView overlay for the React 3D viewer.
    • PermissionsFragment – runtime permissions UX.
  • Views/overlays: SelectionView, SelectionViewLandscape, SnapshotOverlay(… ) – UI chrome for capture/selection.

  • Helpers:

    • FaceLandmarkerHelper – Mediapipe integration.
    • OneEuroFilter – temporal smoothing for pose.
    • VtoViewModel – sends filtered pose to LocalWebServer (React updates).

Data layer & offline cache​

  • Realm: stores local file paths for every downloaded asset, plus lightweight model data to drive the UI offline.
  • MainViewModel is responsible for: counting items → downloading → progress updates → persisting to Realm → exposing final lists to selectors.
  • On runtime, both Kotlin UI and the WebView consume local URIs only.

Local Web app (assets/www)​

  • index.html, manifest.json, React bundle under assets/www/static/.
  • 3D models (*.glb), HDRI environments (*.hdr), brand images, and Mediapipe task files sit alongside.
  • Served by LocalWebServer and displayed in a transparent WebView above the camera feed.
  • Realtime pose/offsets arrive via local HTTP/WebSocket messages from VtoViewModel.

Inactivity & screensaver​

  • InactivityWrapper (Compose): wraps most routes; on timeout returns to video.
  • In VtoActivity, if no face detected for 3 minutes, the activity finishes and the app returns to the looping video.

Asset management​

  • What is downloaded: mirror video(s) for screensaver, brand logos/backgrounds, glasses GLB models, HDR environments, and any auxiliary images.
  • Where: files are stored on device storage with their absolute paths recorded in Realm.
  • How it’s used: UI reads from Realm; WebView sources models/HDR directly via file:// paths provided by LocalWebServer.

Naming & conventions​

  • Feature packages under screens/* (e.g., screens/try_on, screens/model_viewer).
  • ViewModels suffixed with ViewModel.
  • Helpers/utilities in utils/ and VTO-specific code in vto_activity/.
  • Models live in models/; Realm helpers in realm/.