From 5d8ace22bf7dfb29265153ced0de8782e8196955 Mon Sep 17 00:00:00 2001 From: todayama_r <13657682+Corvus400@users.noreply.github.com> Date: Wed, 4 Sep 2024 03:11:05 +0900 Subject: [PATCH 1/4] :recycle: Added loading indicator since it is missing. --- .../contributors/ContributorsScreen.kt | 61 +++++++++++++------ .../ContributorsScreenPresenter.kt | 3 +- 2 files changed, 44 insertions(+), 20 deletions(-) diff --git a/feature/contributors/src/commonMain/kotlin/io/github/droidkaigi/confsched/contributors/ContributorsScreen.kt b/feature/contributors/src/commonMain/kotlin/io/github/droidkaigi/confsched/contributors/ContributorsScreen.kt index c6902b369..16bd74215 100644 --- a/feature/contributors/src/commonMain/kotlin/io/github/droidkaigi/confsched/contributors/ContributorsScreen.kt +++ b/feature/contributors/src/commonMain/kotlin/io/github/droidkaigi/confsched/contributors/ContributorsScreen.kt @@ -1,11 +1,13 @@ package io.github.droidkaigi.confsched.contributors +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items +import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Scaffold import androidx.compose.material3.SnackbarHost @@ -13,6 +15,7 @@ import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.platform.testTag @@ -46,10 +49,18 @@ fun NavGraphBuilder.contributorsScreens( } } -data class ContributorsUiState( - val contributors: PersistentList, - val userMessageStateHolder: UserMessageStateHolder, -) +sealed interface ContributorsUiState { + val userMessageStateHolder: UserMessageStateHolder + + data class Loading( + override val userMessageStateHolder: UserMessageStateHolder, + ): ContributorsUiState + + data class Exists( + override val userMessageStateHolder: UserMessageStateHolder, + val contributors: PersistentList, + ): ContributorsUiState +} @Composable fun ContributorsScreen( @@ -109,21 +120,33 @@ fun ContributorsScreen( } }, ) { padding -> - Contributors( - contributors = uiState.contributors, - onContributorsItemClick = onContributorsItemClick, - contentPadding = PaddingValues(bottom = padding.calculateBottomPadding()), - modifier = Modifier - .fillMaxSize() - .padding(top = padding.calculateTopPadding()) - .let { - if (scrollBehavior != null) { - it.nestedScroll(scrollBehavior.nestedScrollConnection) - } else { - it - } - }, - ) + when (uiState) { + is ContributorsUiState.Exists -> { + Contributors( + contributors = uiState.contributors, + onContributorsItemClick = onContributorsItemClick, + contentPadding = PaddingValues(bottom = padding.calculateBottomPadding()), + modifier = Modifier + .fillMaxSize() + .padding(top = padding.calculateTopPadding()) + .let { + if (scrollBehavior != null) { + it.nestedScroll(scrollBehavior.nestedScrollConnection) + } else { + it + } + }, + ) + } + is ContributorsUiState.Loading -> { + Box( + contentAlignment = Alignment.Center, + modifier = Modifier.padding(padding).fillMaxSize(), + ) { + CircularProgressIndicator() + } + } + } } } diff --git a/feature/contributors/src/commonMain/kotlin/io/github/droidkaigi/confsched/contributors/ContributorsScreenPresenter.kt b/feature/contributors/src/commonMain/kotlin/io/github/droidkaigi/confsched/contributors/ContributorsScreenPresenter.kt index 93a73702b..4028126f4 100644 --- a/feature/contributors/src/commonMain/kotlin/io/github/droidkaigi/confsched/contributors/ContributorsScreenPresenter.kt +++ b/feature/contributors/src/commonMain/kotlin/io/github/droidkaigi/confsched/contributors/ContributorsScreenPresenter.kt @@ -19,7 +19,8 @@ fun contributorsScreenPresenter( val contributors by rememberUpdatedState(contributorsRepository.contributors()) EventEffect(events) { event -> } - ContributorsUiState( + if (contributors.isEmpty()) return@providePresenterDefaults ContributorsUiState.Loading(userMessageStateHolder) + ContributorsUiState.Exists( contributors = contributors, userMessageStateHolder = userMessageStateHolder, ) From 1a8be78bf22e55bf8e8b08c15851bb6378945fc7 Mon Sep 17 00:00:00 2001 From: todayama_r <13657682+Corvus400@users.noreply.github.com> Date: Wed, 4 Sep 2024 03:22:22 +0900 Subject: [PATCH 2/4] :wrench: ./gradlew detekt --auto-correct --- .../droidkaigi/confsched/contributors/ContributorsScreen.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/feature/contributors/src/commonMain/kotlin/io/github/droidkaigi/confsched/contributors/ContributorsScreen.kt b/feature/contributors/src/commonMain/kotlin/io/github/droidkaigi/confsched/contributors/ContributorsScreen.kt index 16bd74215..d90013170 100644 --- a/feature/contributors/src/commonMain/kotlin/io/github/droidkaigi/confsched/contributors/ContributorsScreen.kt +++ b/feature/contributors/src/commonMain/kotlin/io/github/droidkaigi/confsched/contributors/ContributorsScreen.kt @@ -54,12 +54,12 @@ sealed interface ContributorsUiState { data class Loading( override val userMessageStateHolder: UserMessageStateHolder, - ): ContributorsUiState + ) : ContributorsUiState data class Exists( override val userMessageStateHolder: UserMessageStateHolder, val contributors: PersistentList, - ): ContributorsUiState + ) : ContributorsUiState } @Composable From 734b8b3beca5aef257a5c3982c7571f65ea4cbdd Mon Sep 17 00:00:00 2001 From: todayama_r <13657682+Corvus400@users.noreply.github.com> Date: Wed, 4 Sep 2024 06:03:58 +0900 Subject: [PATCH 3/4] :wrench: Fixed so that the build would also pass on the iOS side. Contributors Since it seems that Loading and Exists are not output to XCFrameWork when UiState is a sealed interface, I modified it like this. --- .../KmpPresenterContributorView.swift | 33 +++++++++++-------- .../contributors/ContributorsScreen.kt | 24 +++++++------- .../ContributorsScreenPresenter.kt | 4 +-- 3 files changed, 33 insertions(+), 28 deletions(-) diff --git a/app-ios/Sources/ContributorFeature/KmpPresenterContributorView.swift b/app-ios/Sources/ContributorFeature/KmpPresenterContributorView.swift index 7e354a2c4..6ead06491 100644 --- a/app-ios/Sources/ContributorFeature/KmpPresenterContributorView.swift +++ b/app-ios/Sources/ContributorFeature/KmpPresenterContributorView.swift @@ -21,22 +21,26 @@ struct KmpPresenterContributorView: View { var body: some View { Group { - if let contributors = currentState.map(\.contributors) { - ScrollView { - LazyVStack(spacing: 0) { - ForEach(contributors, id: \.id) { value in - let contributor = Model.Contributor( - id: Int(value.id), - userName: value.username, - profileUrl: value.profileUrl.map { URL(string: $0)! } , - iconUrl: URL(string: value.iconUrl)! - ) - ContributorListItemView( - contributor: contributor, - onContributorButtonTapped: onContributorButtonTapped - ) + if let state = currentState { + if let existsState = state as? Exists { + ScrollView { + LazyVStack(spacing: 0) { + ForEach(existsState.contributors, id: \.id) { value in + let contributor = Model.Contributor( + id: Int(value.id), + userName: value.username, + profileUrl: value.profileUrl.map { URL(string: $0)! }, + iconUrl: URL(string: value.iconUrl)! + ) + ContributorListItemView( + contributor: contributor, + onContributorButtonTapped: onContributorButtonTapped + ) + } } } + } else if state is Loading { + ProgressView() } } else { ProgressView() @@ -51,6 +55,7 @@ struct KmpPresenterContributorView: View { @MainActor private func startListening() async { + // contributorsScreenPresenterStateFlowの非同期処理で状態を監視して更新 let uiStateStateFlow = contributorsScreenPresenterStateFlow(repositories: repositories.map, events: SkieSwiftMutableSharedFlow(events)) for await state in uiStateStateFlow { diff --git a/feature/contributors/src/commonMain/kotlin/io/github/droidkaigi/confsched/contributors/ContributorsScreen.kt b/feature/contributors/src/commonMain/kotlin/io/github/droidkaigi/confsched/contributors/ContributorsScreen.kt index d90013170..dd923ecea 100644 --- a/feature/contributors/src/commonMain/kotlin/io/github/droidkaigi/confsched/contributors/ContributorsScreen.kt +++ b/feature/contributors/src/commonMain/kotlin/io/github/droidkaigi/confsched/contributors/ContributorsScreen.kt @@ -49,18 +49,18 @@ fun NavGraphBuilder.contributorsScreens( } } -sealed interface ContributorsUiState { - val userMessageStateHolder: UserMessageStateHolder +sealed class ContributorsUiState { + abstract val userMessageStateHolder: UserMessageStateHolder +} - data class Loading( - override val userMessageStateHolder: UserMessageStateHolder, - ) : ContributorsUiState +class Loading( + override val userMessageStateHolder: UserMessageStateHolder, +) : ContributorsUiState() - data class Exists( - override val userMessageStateHolder: UserMessageStateHolder, - val contributors: PersistentList, - ) : ContributorsUiState -} +class Exists( + override val userMessageStateHolder: UserMessageStateHolder, + val contributors: PersistentList, +) : ContributorsUiState() @Composable fun ContributorsScreen( @@ -121,7 +121,7 @@ fun ContributorsScreen( }, ) { padding -> when (uiState) { - is ContributorsUiState.Exists -> { + is Exists -> { Contributors( contributors = uiState.contributors, onContributorsItemClick = onContributorsItemClick, @@ -138,7 +138,7 @@ fun ContributorsScreen( }, ) } - is ContributorsUiState.Loading -> { + is Loading -> { Box( contentAlignment = Alignment.Center, modifier = Modifier.padding(padding).fillMaxSize(), diff --git a/feature/contributors/src/commonMain/kotlin/io/github/droidkaigi/confsched/contributors/ContributorsScreenPresenter.kt b/feature/contributors/src/commonMain/kotlin/io/github/droidkaigi/confsched/contributors/ContributorsScreenPresenter.kt index 4028126f4..53ae2aad0 100644 --- a/feature/contributors/src/commonMain/kotlin/io/github/droidkaigi/confsched/contributors/ContributorsScreenPresenter.kt +++ b/feature/contributors/src/commonMain/kotlin/io/github/droidkaigi/confsched/contributors/ContributorsScreenPresenter.kt @@ -19,8 +19,8 @@ fun contributorsScreenPresenter( val contributors by rememberUpdatedState(contributorsRepository.contributors()) EventEffect(events) { event -> } - if (contributors.isEmpty()) return@providePresenterDefaults ContributorsUiState.Loading(userMessageStateHolder) - ContributorsUiState.Exists( + if (contributors.isEmpty()) return@providePresenterDefaults Loading(userMessageStateHolder) + Exists( contributors = contributors, userMessageStateHolder = userMessageStateHolder, ) From 4234e4d89df7922e67c649516297e2af0d710d7b Mon Sep 17 00:00:00 2001 From: todayama_r <13657682+Corvus400@users.noreply.github.com> Date: Wed, 4 Sep 2024 07:11:46 +0900 Subject: [PATCH 4/4] :wastebasket: Remove unnecessary comment. --- .../Sources/ContributorFeature/KmpPresenterContributorView.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/app-ios/Sources/ContributorFeature/KmpPresenterContributorView.swift b/app-ios/Sources/ContributorFeature/KmpPresenterContributorView.swift index 6ead06491..c9cf9f494 100644 --- a/app-ios/Sources/ContributorFeature/KmpPresenterContributorView.swift +++ b/app-ios/Sources/ContributorFeature/KmpPresenterContributorView.swift @@ -55,7 +55,6 @@ struct KmpPresenterContributorView: View { @MainActor private func startListening() async { - // contributorsScreenPresenterStateFlowの非同期処理で状態を監視して更新 let uiStateStateFlow = contributorsScreenPresenterStateFlow(repositories: repositories.map, events: SkieSwiftMutableSharedFlow(events)) for await state in uiStateStateFlow {