mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-04-09 02:43:29 +08:00
fix: address remaining PR review comments for Kotlin/Android/KMP docs
This commit is contained in:
@@ -15,14 +15,14 @@ Prefer constructor injection. Use Koin (KMP) or Hilt (Android-only):
|
|||||||
// Koin — declare modules
|
// Koin — declare modules
|
||||||
val dataModule = module {
|
val dataModule = module {
|
||||||
single<ItemRepository> { ItemRepositoryImpl(get(), get()) }
|
single<ItemRepository> { ItemRepositoryImpl(get(), get()) }
|
||||||
factory { GetItemsUseCase(get()) }
|
factory { GetItemUseCase(get()) }
|
||||||
viewModelOf(::ItemListViewModel)
|
viewModelOf(::ItemListViewModel)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hilt — annotations
|
// Hilt — annotations
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class ItemListViewModel @Inject constructor(
|
class ItemListViewModel @Inject constructor(
|
||||||
private val getItems: GetItemsUseCase
|
private val getItem: GetItemUseCase
|
||||||
) : ViewModel()
|
) : ViewModel()
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ data class ScreenState(
|
|||||||
val isLoading: Boolean = false
|
val isLoading: Boolean = false
|
||||||
)
|
)
|
||||||
|
|
||||||
class ScreenViewModel(private val useCase: GetItemsUseCase) : ViewModel() {
|
class ScreenViewModel(private val useCase: GetItemUseCase) : ViewModel() {
|
||||||
private val _state = MutableStateFlow(ScreenState())
|
private val _state = MutableStateFlow(ScreenState())
|
||||||
val state = _state.asStateFlow()
|
val state = _state.asStateFlow()
|
||||||
|
|
||||||
@@ -90,21 +90,21 @@ expect class SecureStorage {
|
|||||||
actual fun platformName(): String = "Android"
|
actual fun platformName(): String = "Android"
|
||||||
actual class SecureStorage {
|
actual class SecureStorage {
|
||||||
actual fun save(key: String, value: String) { /* EncryptedSharedPreferences */ }
|
actual fun save(key: String, value: String) { /* EncryptedSharedPreferences */ }
|
||||||
actual fun get(key: String): String? { /* ... */ }
|
actual fun get(key: String): String? = null /* ... */
|
||||||
}
|
}
|
||||||
|
|
||||||
// iosMain
|
// iosMain
|
||||||
actual fun platformName(): String = "iOS"
|
actual fun platformName(): String = "iOS"
|
||||||
actual class SecureStorage {
|
actual class SecureStorage {
|
||||||
actual fun save(key: String, value: String) { /* Keychain */ }
|
actual fun save(key: String, value: String) { /* Keychain */ }
|
||||||
actual fun get(key: String): String? { /* ... */ }
|
actual fun get(key: String): String? = null /* ... */
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Coroutine Patterns
|
## Coroutine Patterns
|
||||||
|
|
||||||
- Use `viewModelScope` in ViewModels, `coroutineScope` for structured child work
|
- Use `viewModelScope` in ViewModels, `coroutineScope` for structured child work
|
||||||
- Use `stateIn(WhileSubscribed(5_000))` for StateFlow from cold Flows
|
- Use `stateIn(viewModelScope, SharingStarted.WhileSubscribed(5_000), initialValue)` for StateFlow from cold Flows
|
||||||
- Use `supervisorScope` when child failures should be independent
|
- Use `supervisorScope` when child failures should be independent
|
||||||
|
|
||||||
## Builder Pattern with DSL
|
## Builder Pattern with DSL
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ paths:
|
|||||||
fun `loading state emitted then data`() = runTest {
|
fun `loading state emitted then data`() = runTest {
|
||||||
val repo = FakeItemRepository()
|
val repo = FakeItemRepository()
|
||||||
repo.addItem(testItem)
|
repo.addItem(testItem)
|
||||||
val viewModel = ItemListViewModel(GetItemsUseCase(repo))
|
val viewModel = ItemListViewModel(GetItemUseCase(repo))
|
||||||
|
|
||||||
viewModel.state.test {
|
viewModel.state.test {
|
||||||
assertEquals(ItemListState(), awaitItem()) // initial state
|
assertEquals(ItemListState(), awaitItem()) // initial state
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ data class ItemListState(
|
|||||||
)
|
)
|
||||||
|
|
||||||
class ItemListViewModel(
|
class ItemListViewModel(
|
||||||
private val getItems: GetItemsUseCase
|
private val getItems: GetItemUseCase
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
private val _state = MutableStateFlow(ItemListState())
|
private val _state = MutableStateFlow(ItemListState())
|
||||||
val state: StateFlow<ItemListState> = _state.asStateFlow()
|
val state: StateFlow<ItemListState> = _state.asStateFlow()
|
||||||
|
|||||||
@@ -218,7 +218,7 @@ viewModelScope.launch {
|
|||||||
@Test
|
@Test
|
||||||
fun `search updates item list`() = runTest {
|
fun `search updates item list`() = runTest {
|
||||||
val fakeRepository = FakeItemRepository(items = testItems)
|
val fakeRepository = FakeItemRepository(items = testItems)
|
||||||
val viewModel = ItemListViewModel(GetItemsUseCase(fakeRepository))
|
val viewModel = ItemListViewModel(GetItemUseCase(fakeRepository))
|
||||||
|
|
||||||
viewModel.state.test {
|
viewModel.state.test {
|
||||||
assertEquals(ItemListState(), awaitItem()) // initial
|
assertEquals(ItemListState(), awaitItem()) // initial
|
||||||
|
|||||||
Reference in New Issue
Block a user