# Fluffytrix Agent Guidelines ## Project Overview Fluffytrix is an Android Matrix chat client with a Discord-like UI. Built with Kotlin, targeting Android 14+ (minSdk 34, targetSdk 36, compileSdk 36). **Package**: `com.example.fluffytrix` **Build system**: Gradle with KotlinDSL, version catalog at `gradle/libs.versions.toml` **DI**: Koin **State management**: Jetpack Compose StateFlow, ViewModel **UI framework**: Jetpack Compose with Material 3 (Dynamic Colors) **Protocol**: Trixnity SDK for Matrix **Storage**: Room Database, DataStore Preferences **Async**: Kotlin Coroutines --- ## Build Commands ```bash ./gradlew assembleDebug # Build debug APK (minified for performance) ./gradlew assembleRelease # Build release APK ./gradlew test # Run all unit tests ./gradlew connectedAndroidTest # Run instrumented tests on device ./gradlew testDebugUnitTest --tests "com.example.fluffytrix.*" # Run single test class ./gradlew app:testDebugUnitTest --tests "LoginViewModelTest" # Run specific test ``` - Debug builds use R8 with `isDebuggable = true` for balanced speed/debuggability - Instrumented tests require a connected device or emulator --- ## Testing **Unit tests**: `app/src/test/java/` **Instrumented tests**: `app/src/androidTest/java/` **Single test**: `./gradlew testDebugUnitTest --tests "com.example.fluffytrix.ui.main.LoginViewModelTest"` --- ## Code Style Guidelines ### Kotlin Conventions - **Android Official Kotlin style** (`kotlin.code.style=official`) - File naming: `PascalCase.kt` (e.g., `MainViewModel.kt`) - Class naming: `PascalCase` (e.g., `AuthRepository`, `MainViewModel`) - Function/property naming: `camelCase` (e.g., `sendMessage`, `selectedChannel`) - Constants: `PascalCase` for top-level constants - **Never use underscores in variable names** ### Imports - Explicit imports only (no wildcards) - Group: Android/X → Kotlin → Javax/Java → Third-party → Same package - Example: ```kotlin import android.os.Bundle import androidx.compose.material3.Text import kotlinx.coroutines.flow.StateFlow import net.folivo.trixnity.client.MatrixClient import com.example.fluffytrix.ui.theme.FluffytrixTheme ``` ### Types & Error Handling - Prefer `val` over `var` (immutable data) - Use `StateFlow` for observable ViewModel state, `Flow` for read-only streams - Use `suspend` for async operations, `Result` for failing operations - `try-catch` with `catch (_: Exception) { }` for graceful degradation in ViewModels - Use `?:` operators when appropriate, **never crash on recoverable errors** ### Compose & ViewModels - Use `@Composable` for all UI functions; use `MaterialTheme` for consistent theming - Discord-like layout: space sidebar → channel list → message area → member list - Use `Modifier.padding()`, `wrapContentWidth()`, `fillMaxWidth()` appropriately - Inject deps via constructor with Koin; use `viewModelScope` for coroutines - Cache expensive operations (e.g., `messageCache`, `memberCache`) ### Coroutines & Data Layer - `Dispatchers.Default` for CPU work, `Dispatchers.IO` for I/O operations - Cancel jobs on ViewModel cleanup: `job?.cancel()` - Use `Room` for persistent storage; `DataStore Preferences` for small key-value data - Prefer Flow-based APIs; cache in ViewModels ### Naming Conventions - State Flow: `_state` (private) / `state` (public) - Repositories: `AuthRepository`, `MessageRepository` - ViewModels: `MainViewModel`, `LoginViewModel` - UI composables: `MainScreen`, `ChannelList`, `MessageItem` - Models: `MessageItem`, `ChannelItem`, `SpaceItem` - Matrix IDs: Use `RoomId`, `UserId` types; access `.full` for strings --- ## Architecture Patterns **Layered Architecture**: ``` ui/ — ViewModels, Screens, Navigation data/ — Repositories, storage, models di/ — Koin modules ui/theme/ — Material 3 Theme ``` **Koin DI**: - `appModule`: ViewModel injection - `dataModule`: Singleton repositories/UI Flow: NavHost in `MainActivity` with `FluffytrixTheme`, ViewModels expose StateFlow, screens observe with `collectAsState()` --- ## Key Dependencies - **Compose BOM**: `2025.06.00`, **Kotlin**: `2.2.10`, **AGP**: `9.0.1` - **Koin**: `4.1.1`, **Trixnity**: `4.22.7`, **Ktor**: `3.3.0` - **Coroutines**: `1.10.2`, **DataStore**: `1.1.7`, **Coil**: `3.2.0`