CLAUDE.md 3.6 KB

Simplauncher

Keep this file under 100 lines. Prefer terse descriptions. Don't duplicate what's in README.md or DEVELOPMENT.md.

Development

export ANDROID_HOME=/home/user/android-sdk
./gradlew assembleDebug        # Build debug APK
./gradlew assembleRelease      # Build release/production APK
./gradlew test                 # Run unit tests (JUnit 5)

Debug APK: app/build/outputs/apk/debug/com.simplauncher.apk Release APK: app/build/outputs/apk/release/com.simplauncher.apk

Versioning

Version tracked in app/build.gradle.kts: versionName (semver) + versionCode (integer).

  • PATCH (1.0.x): bug fixes, visual tweaks
  • MINOR (1.x.0): new features, settings, UI additions
  • MAJOR (x.0.0): breaking changes, major redesigns
  • Increment versionCode by 1 on every release regardless of semver bump.
  • Tag every release: git tag -a v1.0.0 -m "description" then git push origin v1.0.0
  • IMPORTANT: After any version bump, remind user to upload the release APK to Gogs releases page at https://gogs.altsol.dev/claude/simplauncher/releases

Repository

  • Remote: https://gogs.altsol.dev/claude/simplauncher.git
  • Branch: master only
  • Forked from Unlauncher 2.1.1 (itself a fork of Slim Launcher)

Architecture

Single-activity (MainActivity), multi-fragment app using Navigation Component. MVVM-lite: fragments observe DataRepository via LiveData. Hilt DI throughout.

Package: com.simplauncher — all source under app/src/main/java/com/simplauncher/

Navigation (nav_graph.xml)

HomeFragment (start) → OptionsFragment
  → CustomizeHomeFragment → CustomizeHomeAppsAddAppFragment
  → CustomizeAppDrawerFragment → CustomizeVisibleAppsFragment
                                → CustomizeSearchFieldFragment
                                → CustomizeFoldersFragment → CustomizeFolderDetailFragment

Data Layer

Three storage systems (migrating everything to Proto DataStore):

  1. Proto DataStore (primary): core_preferences.proto, unlauncher_apps.proto, quick_button_preferences.proto, app_drawer_folders.proto
  2. Room DB (legacy): BaseDatabase with HomeApp entity, 9 migrations
  3. SharedPreferences (legacy): being migrated away

DataRepository wraps DataStore with LiveData observation, sync get(), and updateAsync(). All new data should use Proto DataStore.

Hilt DI

  • SingletonComponent: 4 DataStore instances (incl. AppDrawerFolders), BaseDatabase
  • ActivityComponent: CorePreferences repo (@WithActivityLifecycle)
  • FragmentComponent: All 4 repos (@WithFragmentLifecycle), FragmentManager, CoroutineScope

UI Patterns

  • View Binding on all fragments
  • MotionLayout for home→drawer transition (swipe up)
  • Pub-sub: MainActivity (IPublisher) → Fragments (ISubscriber) for back/home events
  • App drawer folders: alignment-aware arrows, animated expand/collapse, auto-collapse on home
  • Folder detail settings: checkbox app selector with 3-dot menu (rename/delete)
  • Home screen: up to 6 apps, 3 quick buttons (call/options/camera), clock, date, search bar

Themes

9 themes: system (light/dark), midnight, jupiter, teal, candy, pastel, noon, vlad, groovy.

Permissions

QUERY_ALL_PACKAGES, REQUEST_DELETE_PACKAGES, EXPAND_STATUS_BAR, SET_WALLPAPER, SET_ALARM

Testing

JUnit 5 + Kotest assertions + MockK. Coverage excludes generated proto/Hilt classes.

Conventions

  • Kotlin only
  • New preferences → Proto DataStore (never SharedPreferences or Room)
  • Fragment lifecycle: onCreateView (inflate) → onViewCreated (setup) → onStart (attach pub-sub) → onStop (detach)
  • ProGuard keeps protobuf generated classes