From 93f484dc9e8737ebe91b110ea2343895709dbc2c Mon Sep 17 00:00:00 2001 From: bpedryc Date: Mon, 3 Jul 2023 10:43:51 +0200 Subject: [PATCH] Implement the favorite behavior changes on iOS --- .../kampkit/android/ui/BreedDetailsScreen.kt | 2 +- .../kampkit/android/ui/BreedsScreen.kt | 2 +- ios/KaMPKitiOS/BreedDetailsScreen.swift | 26 ++++++++++++++----- ios/KaMPKitiOS/Breeds/BreedsViewModel.swift | 14 +++++----- ios/KaMPKitiOS/BreedsScreen.swift | 8 +++--- .../ui/breedDetails/BreedDetailsViewModel.kt | 6 +++-- .../kampkit/ui/breeds/BreedsViewModel.kt | 2 +- .../co/touchlab/kampkit/BreedViewModelTest.kt | 2 +- 8 files changed, 39 insertions(+), 23 deletions(-) diff --git a/app/src/main/kotlin/co/touchlab/kampkit/android/ui/BreedDetailsScreen.kt b/app/src/main/kotlin/co/touchlab/kampkit/android/ui/BreedDetailsScreen.kt index f43f3646..75b10a19 100644 --- a/app/src/main/kotlin/co/touchlab/kampkit/android/ui/BreedDetailsScreen.kt +++ b/app/src/main/kotlin/co/touchlab/kampkit/android/ui/BreedDetailsScreen.kt @@ -41,7 +41,7 @@ fun BreedDetailsScreen( Spacer(Modifier.width(4.dp)) FavoriteIcon( breed = state.breed, - onClick = viewModel::toggleFavorite + onClick = viewModel::onFavoriteClick ) } } diff --git a/app/src/main/kotlin/co/touchlab/kampkit/android/ui/BreedsScreen.kt b/app/src/main/kotlin/co/touchlab/kampkit/android/ui/BreedsScreen.kt index 0c358704..abbe659b 100644 --- a/app/src/main/kotlin/co/touchlab/kampkit/android/ui/BreedsScreen.kt +++ b/app/src/main/kotlin/co/touchlab/kampkit/android/ui/BreedsScreen.kt @@ -56,7 +56,7 @@ fun BreedsScreen( onRefresh = { viewModel.refreshBreeds() }, onSuccess = { data -> log.v { "View updating with ${data.size} breeds" } }, onError = { exception -> log.e { "Displaying error: $exception" } }, - onBreedClick = { viewModel.navigateToDetails(it) }, + onBreedClick = { viewModel.onBreedClick(it) }, ) } diff --git a/ios/KaMPKitiOS/BreedDetailsScreen.swift b/ios/KaMPKitiOS/BreedDetailsScreen.swift index 0b2dc87c..2fd88cd2 100644 --- a/ios/KaMPKitiOS/BreedDetailsScreen.swift +++ b/ios/KaMPKitiOS/BreedDetailsScreen.swift @@ -13,10 +13,10 @@ import KMPNativeCoroutinesCombine import Foundation class BreedDetailsViewModel: ObservableObject { - private var viewModel: BreedDetailsViewModelDelegate + private var viewModelDelegate: BreedDetailsViewModelDelegate init(breedId: Int64) { - self.viewModel = KotlinDependencies.shared.getBreedDetailsViewModel(breedId: breedId) + self.viewModelDelegate = KotlinDependencies.shared.getBreedDetailsViewModel(breedId: breedId) } @Published @@ -24,8 +24,12 @@ class BreedDetailsViewModel: ObservableObject { private var cancellables = [AnyCancellable]() + func onFavoriteClick() { + viewModelDelegate.onFavoriteClick() + } + func activate() { - createPublisher(for: viewModel.detailsStateFlow) + createPublisher(for: viewModelDelegate.detailsStateFlow) .sink { _ in } receiveValue: { [weak self] (detailsState: BreedDetailsViewState) in self?.detailsState = detailsState } @@ -38,7 +42,7 @@ class BreedDetailsViewModel: ObservableObject { } deinit { - viewModel.clear() + viewModelDelegate.clear() } } @@ -48,7 +52,9 @@ struct BreedDetailsScreen: View { var body: some View { BreedDetailsContent( - breedName: viewModel.detailsState.breed.name + breedName: viewModel.detailsState.breed.name, + isBreedFavorite: viewModel.detailsState.breed.favorite, + onFavoriteClick: { viewModel.onFavoriteClick() } ) .onAppear(perform: { viewModel.activate() @@ -61,7 +67,15 @@ struct BreedDetailsScreen: View { struct BreedDetailsContent: View { var breedName: String + var isBreedFavorite: Bool + var onFavoriteClick: () -> Void var body: some View { - Text(breedName) + HStack { + Text(breedName) + Button(action: onFavoriteClick) { + Image(systemName: (!isBreedFavorite) ? "heart" : "heart.fill") + .padding(4.0) + } + } } } diff --git a/ios/KaMPKitiOS/Breeds/BreedsViewModel.swift b/ios/KaMPKitiOS/Breeds/BreedsViewModel.swift index ba759463..8229929d 100644 --- a/ios/KaMPKitiOS/Breeds/BreedsViewModel.swift +++ b/ios/KaMPKitiOS/Breeds/BreedsViewModel.swift @@ -12,20 +12,20 @@ import shared import KMPNativeCoroutinesCombine class BreedsViewModel: ObservableObject { - + @Published var state: BreedViewState = BreedViewState.companion.default() - + private var navCoordinator: BreedsNavCoordinator private var viewModelDelegate: BreedsViewModelDelegate = KotlinDependencies.shared.getBreedsViewModel() init(navCoordinator: BreedsNavCoordinator) { self.navCoordinator = navCoordinator } private var cancellables = [AnyCancellable]() - + deinit { viewModelDelegate.clear() } - + func subscribeState() { createPublisher(for: viewModelDelegate.breedStateFlow) .sink { _ in } receiveValue: { [weak self] (breedState: BreedViewState) in @@ -34,7 +34,7 @@ class BreedsViewModel: ObservableObject { } .store(in: &cancellables) } - + private func handleNavRequests(breedsState: BreedViewState) { if let navRequest = breedsState.breedsNavRequest as? BreedsNavRequest.ToDetails { self.navCoordinator.onBreedDetailsRequest(breedId: navRequest.breedId) @@ -47,8 +47,8 @@ class BreedsViewModel: ObservableObject { cancellables.removeAll() } - func onBreedFavorite(_ breed: Breed) { - viewModelDelegate.updateBreedFavorite(breed: breed) + func onBreedClick(_ breedId: Int64) { + viewModelDelegate.onBreedClick(breedId: breedId) } func refresh() { diff --git a/ios/KaMPKitiOS/BreedsScreen.swift b/ios/KaMPKitiOS/BreedsScreen.swift index 281e2ce4..019f9124 100644 --- a/ios/KaMPKitiOS/BreedsScreen.swift +++ b/ios/KaMPKitiOS/BreedsScreen.swift @@ -23,7 +23,7 @@ struct BreedsScreen: View { loading: viewModel.state.isLoading, breeds: viewModel.state.breeds, error: viewModel.state.error, - onBreedFavorite: { viewModel.onBreedFavorite($0) }, + onBreedClick: { viewModel.onBreedClick($0) }, refresh: { viewModel.refresh() } ) .onAppear(perform: { @@ -39,7 +39,7 @@ struct BreedListContent: View { var loading: Bool var breeds: [Breed]? var error: String? - var onBreedFavorite: (Breed) -> Void + var onBreedClick: (Int64) -> Void var refresh: () -> Void var body: some View { @@ -48,7 +48,7 @@ struct BreedListContent: View { if let breeds = breeds { List(breeds, id: \.id) { breed in BreedRowView(breed: breed) { - onBreedFavorite(breed) + onBreedClick(breed.id) } } } @@ -91,7 +91,7 @@ struct BreedListScreen_Previews: PreviewProvider { Breed(id: 1, name: "australian", favorite: true) ], error: nil, - onBreedFavorite: { _ in }, + onBreedClick: { _ in }, refresh: {} ) } diff --git a/shared/src/commonMain/kotlin/co/touchlab/kampkit/ui/breedDetails/BreedDetailsViewModel.kt b/shared/src/commonMain/kotlin/co/touchlab/kampkit/ui/breedDetails/BreedDetailsViewModel.kt index 7ed0b3c1..f279354a 100644 --- a/shared/src/commonMain/kotlin/co/touchlab/kampkit/ui/breedDetails/BreedDetailsViewModel.kt +++ b/shared/src/commonMain/kotlin/co/touchlab/kampkit/ui/breedDetails/BreedDetailsViewModel.kt @@ -44,7 +44,9 @@ class BreedDetailsViewModel( } } - fun toggleFavorite() = viewModelScope.launch { - dogRepository.updateBreedFavorite(breedId) + fun onFavoriteClick() { + viewModelScope.launch { + dogRepository.updateBreedFavorite(breedId) + } } } diff --git a/shared/src/commonMain/kotlin/co/touchlab/kampkit/ui/breeds/BreedsViewModel.kt b/shared/src/commonMain/kotlin/co/touchlab/kampkit/ui/breeds/BreedsViewModel.kt index 2b6be747..c8bf8701 100644 --- a/shared/src/commonMain/kotlin/co/touchlab/kampkit/ui/breeds/BreedsViewModel.kt +++ b/shared/src/commonMain/kotlin/co/touchlab/kampkit/ui/breeds/BreedsViewModel.kt @@ -79,7 +79,7 @@ class BreedsViewModel( } } - fun navigateToDetails(breedId: Long): Job { + fun onBreedClick(breedId: Long): Job { return viewModelScope.launch { mutableBreedState.update { it.copy(breedsNavRequest = BreedsNavRequest.ToDetails(breedId)) diff --git a/shared/src/commonTest/kotlin/co/touchlab/kampkit/BreedViewModelTest.kt b/shared/src/commonTest/kotlin/co/touchlab/kampkit/BreedViewModelTest.kt index 44af3511..161078e1 100644 --- a/shared/src/commonTest/kotlin/co/touchlab/kampkit/BreedViewModelTest.kt +++ b/shared/src/commonTest/kotlin/co/touchlab/kampkit/BreedViewModelTest.kt @@ -149,7 +149,7 @@ class BreedViewModelTest { @Test fun `Navigate to breed details`() = runTest { dbHelper.insertBreeds(breedNames) - viewModel.navigateToDetails(1).join() + viewModel.onBreedClick(1).join() viewModel.breedState.test { val state = awaitItem()