Skip to content

tomasholub/data-ponte.android

Repository files navigation

DataPonte Android

Android client for the DataPonte real-time card tracking app. Mirrors the feature set of the iOS app (~/Devel/data-ponte.ios) and shares the same Supabase backend as the web app (~/Devel/data-ponte).

Tech stack

Layer Technology
Language Kotlin 2.0
UI Jetpack Compose + Material 3
Backend Supabase (supabase-kt 3.1.4 via BOM)
HTTP engine OkHttp via Ktor 3.0.3
Async Coroutines + Flow
Serialization kotlinx.serialization
Navigation Navigation Compose
State ViewModel + StateFlow
Min SDK API 26 (Android 8.0)

Setup

1. Prerequisites

  • Android Studio Ladybug (2024.2) or later
  • JDK 17+

2. Supabase credentials

Copy local.properties.example to local.properties and fill in your credentials:

sdk.dir=/Users/YourName/Library/Android/sdk
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_ANON_KEY=your-anon-key-here

local.properties is git-ignored and must never be committed.

3. Gradle wrapper

The project includes gradle/wrapper/gradle-wrapper.properties but not the binary gradle-wrapper.jar. Android Studio will download it automatically when you open the project. Alternatively, run:

gradle wrapper --gradle-version=8.9

4. Open in Android Studio

File → Open → select the data-ponte.android directory. Android Studio will sync Gradle and download all dependencies.

5. Run

Select a device/emulator and press Run (▶). The app will prompt you to sign in with your Supabase account.

Project structure

app/src/main/java/com/dataponte/app/
├── DataPonteApp.kt              # Application class
├── MainActivity.kt              # Single activity, sets up Compose + theme
├── models/                      # Serializable data classes (DB table mirrors)
│   ├── CardTypes.kt             # CardType, CardSize, CardAccess enums
│   ├── CardDefinition.kt        # CardDefinitionOptions, StatusOption, etc.
│   ├── Card.kt                  # Card + AssignedCard
│   ├── CardValue.kt             # CardValue + CardValueBroadcast
│   ├── CardTemplate.kt
│   ├── Profile.kt
│   ├── UserCard.kt
│   ├── TeamMember.kt            # TeamMember + UserDirectoryEntry
│   └── CalendarEvent.kt
├── repositories/                # Supabase data-access layer
│   ├── AuthRepository.kt
│   ├── CardRepository.kt
│   ├── CardValueRepository.kt
│   ├── ProfileRepository.kt
│   ├── TeamRepository.kt
│   ├── UserCardRepository.kt
│   ├── TemplateRepository.kt
│   ├── CalendarEventRepository.kt
│   └── RealtimeService.kt       # Supabase Realtime broadcast subscription
├── support/                     # Utilities
│   ├── SupabaseClient.kt        # Singleton client setup
│   ├── SessionStore.kt          # ViewModel holding auth state + profile
│   ├── OnboardingFlags.kt       # First-launch flag (SharedPreferences)
│   ├── DateTimeFormats.kt       # DateTimeFormatId enum
│   ├── DateFormatting.kt        # Date/time formatting helpers
│   ├── CardValueDisplay.kt      # Type-aware value → display string
│   ├── CardIcon.kt              # Lucide → Material icon mapping + colors
│   ├── CardStatistics.kt        # Statistics computation
│   └── LocaleManager.kt        # Language switching via AppCompatDelegate
├── navigation/
│   ├── Screen.kt                # Sealed class of all routes
│   └── AppNavigation.kt         # NavHost + bottom tab bar
└── features/
    ├── auth/                    # Sign in, sign up, forgot password
    ├── cards/                   # Cards list, detail, value editor, history,
    │                            # statistics, creation, settings, calendar,
    │                            # assigned users, icon picker, markdown
    ├── manager/                 # Team management
    ├── onboarding/              # Welcome screen
    └── settings/                # User settings

Sync with web / iOS

See SYNC.md for the current sync baseline and instructions for porting new web features to this app.

Architecture notes

  • Repository pattern: each repository wraps supabase.postgrest.from(…) calls. No DI framework — repositories are instantiated directly in ViewModels (same approach as iOS).
  • SessionStore: a top-level ViewModel holding auth state and the current Profile. Provided via viewModel() at the MainActivity level and passed down as a parameter where needed.
  • Realtime: RealtimeService subscribes to the user:{userId} broadcast channel and exposes updates as a SharedFlow. CardsListViewModel collects from it and applies synthetic CardValue updates without a network round-trip (mirrors iOS).
  • Locale: language switching uses AppCompatDelegate.setApplicationLocales() — no Activity restart needed on API 33+. Older devices may need a restart.
  • Theme: Material 3 with dynamic color (API 31+) or a static green-tinted scheme on older devices.

Dependencies to review before release

  • Check supabase-kt releases for version updates (currently pinned to 3.1.4 via BOM).
  • Review Proguard rules in app/proguard-rules.pro for release builds.

About

Android client for DataPonte — Kotlin/Compose, Supabase backend

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages