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.
Navigation & screens (Compose)
-
Entry
entry_screen/MirrorIdEntryScreen– submit Mirror ID; triggers full sync.- Screensaver – video player (portrait/landscape variants) with tap-to-start.
-
Portrait flow
gender_selector/GenderSelectorframe_selector/FrameSelectorbrand_selector/BrandSelector,BrandViewglasses_selector/GlassesSelectormodel_viewer/ModelViewer– 3D viewer (WebView React + Kotlin UI controls)vto_screen/VtoScreen– route toVtoActivity
-
Landscape flow
- From video → directly to
VtoActivitywith auto-advancing selection (10s per item).
- From video → directly to
-
Global
language_selector/LanguageSelector– accessible from any page.main/MainScreen– hosts theNavHost, 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 underassets/www/static/.- 3D models (
*.glb), HDRI environments (*.hdr), brand images, and Mediapipe task files sit alongside. - Served by
LocalWebServerand 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 byLocalWebServer.
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 invto_activity/. - Models live in
models/; Realm helpers inrealm/.