Skip to main content
Version: 1.0.0

Structure

Details on architecture, folders, main files, and asset management for the ARShades Android app and its Instant App.


Architectural overview

  • Pattern: MVVM + Repository + DI (Hilt)
  • UI: Jetpack Compose + XML (hybrid, Compose is progressively adopted)
  • Rendering: ARCore + Sceneform
  • Data: Firebase (Firestore, Storage, Dynamic Links, Messaging, App Check) with optional Realm cache (full app only)
  • Navigation: Jetpack Navigation (Compose + Fragments), side menu
  • Instant App: Smaller surface mirroring the Try-On flow with minimal Firebase + model hydration

Top-level layout

ARShades/
├─ app/ # Main Android app module
│ ├─ manifests/ # AndroidManifest + App metadata
│ ├─ kotlin+java/it.spaarkly.arshades/
│ ├─ res/ # XML layouts, drawables, strings, themes

├─ arshades_instant/ # Instant App module (lightweight Try-On)
├─ ARShadesFramework/ # Shared framework (contracts, utils, domain models)
├─ ARShadesInterfaces/ # Interfaces across modules
├─ ARShadesUiComponents/ # Shared UI components (Compose & XML)

App module (app/)

Components

Reusable UI building blocks in Compose/XML:

  • components/ → Buttons, CatalogueComponents, ColorDotComponents, FilterComponents, GlassesCard, etc.
  • general_views/, general_purpose_widgets/ → generic views/widgets

Screens (feature-based)

  • screens/brand/ → BrandPageFragment, BrandListScreen
  • screens/catalogue/ → FragmentCatalogue, CatalogueViewModel
  • screens/contacts/ → ContactsFragment, ContactsScreenViewModel
  • screens/favourites/ → FavouritesFragment, FavouritesScreenViewModel
  • screens/filters/ → FiltersViewModel
  • screens/facial_metric/ → FacialMetricScreenViewModel, Measurement
  • screens/notification/ → NotificationFragment, NotificationScreenViewModel
  • screens/try_on/ → TryOnActivity, TryOnScreenViewModel, FacialMetricsController
  • screens/splash/ → SplashScreen.kt, AppConfigViewModel
  • screens/terms_and_conditions/ → TermsAndConditionsActivity, LegalViewModel

Data & persistence

  • repository/

    • Firebase/read → AppConfig, Brand, Catalog, Product, Variant, Legal, etc.
    • Firebase/write → SessionRepository, CountersRepository
    • Realm/ → Local Realm repos for Favorites, Notifications, Brands
  • database/

    • firebaseDB.write.SessionDB
    • realmDB/ + IRealmDB
  • model/ → Core domain: AppConfig, Brand, Catalog, CatalogProduct, CatalogVariant, UserSession, DynamicLinkObject, etc.

  • session/ → CurrentSession, GlassesSession, ModelSession, UserDataMetrics

Services & utils

  • services/FirebaseNotificationService → handles push notifications
  • utils/ → NetworkUtils, PermissionManager, SharedPrefs, TakePicsUtility, SideMenuPageSwitcher
  • ui.theme/ → Compose theme files (Color.kt, Theme.kt, Type.kt)
  • di/ → Hilt AppModule

Instant App module (arshades_instant/)

Lightweight subset of the app:

  • Keeps only Dynamic Link hydration, Try-On, and minimal repositories
  • Mirrors models (UserAr, Brand, Catalog, Occhiale, etc.) and SessionDB
  • Slimmed-down repository.firebase.read for fetching Try-On context
  • No Realm, reduced UI

Shared modules

  • ARShadesFramework → Common contracts, utils, interfaces
  • ARShadesInterfaces → Defines module interfaces
  • ARShadesUiComponents → Shared Compose widgets & XML components across app/instant

Asset management

  • 3D models (GLB/Sceneform) → Downloaded on demand via Firebase Storage, rendered with Sceneform
  • Images (PNG/JPG, VectorDrawables) → In res/drawable/, fetched & cached from Firebase
  • GIF/Animations → Splash + empty/error states (res/drawable/)
  • Layouts → Hybrid Compose + XML (res/layout/), with gradual Compose migration
  • Themes & Stylesres/values/ (colors, dimens, strings, themes)

Build setup

  • Gradle modules: app, arshades_instant, ARShadesFramework, ARShadesInterfaces, ARShadesUiComponents
  • Hilt for DI
  • Proguard/R8 configs per module
  • Firebase BoM manages Crashlytics, Analytics, Perf, Messaging, Firestore, Storage, Auth, Dynamic Links
  • Realm for local caching (full app only)
  • Navigation Component for deep link + side menu routing
  • Play Core for in-app updates & reviews
  • App Signing: Release config via signingConfigs.release in build.gradle

Data flow (high level)

  1. Startup

    • Splash → AppConfig fetch (Firestore)
    • Hydrate deep link (c, m) if present
  2. No deep link

    • Brands (from AppConfig + Realm-learned) → Try-On
  3. Deep link (c, m)

    • Hydrate catalogue/variant/product/siblings from Firebase
    • If catalogue unknown, persist to Realm for next sessions
  4. User interactions

    • ViewModels drive UI (Compose/XML)
    • Repositories fetch/write to Firebase + Realm
    • State persists via Realm + SharedPrefs
  5. AR Rendering

    • ARCore + Sceneform pipeline for Try-On (glasses fitting, skin metrics)

Naming & conventions

  • Kotlin packages follow feature-first naming (screens/try_on, screens/catalogue, repository/firebase)
  • ViewModels suffixed with ViewModel
  • Repositories suffixed with Repository (BrandRepository, SessionRepository)
  • Realm interfaces prefixed with I* (e.g., IBrandRepository)
  • Fragments/Activities map 1:1 with XML layouts (when not Compose)