diff --git a/app-ios/Sources/ContributorFeature/KmpPresenterContributorView.swift b/app-ios/Sources/ContributorFeature/KmpPresenterContributorView.swift index 30ce8cdea..46ef56ee2 100644 --- a/app-ios/Sources/ContributorFeature/KmpPresenterContributorView.swift +++ b/app-ios/Sources/ContributorFeature/KmpPresenterContributorView.swift @@ -23,22 +23,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() 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..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 @@ -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( +sealed class ContributorsUiState { + abstract val userMessageStateHolder: UserMessageStateHolder +} + +class Loading( + override val userMessageStateHolder: UserMessageStateHolder, +) : ContributorsUiState() + +class Exists( + override val userMessageStateHolder: UserMessageStateHolder, val contributors: PersistentList, - val userMessageStateHolder: UserMessageStateHolder, -) +) : 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 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 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..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,7 +19,8 @@ fun contributorsScreenPresenter( val contributors by rememberUpdatedState(contributorsRepository.contributors()) EventEffect(events) { event -> } - ContributorsUiState( + if (contributors.isEmpty()) return@providePresenterDefaults Loading(userMessageStateHolder) + Exists( contributors = contributors, userMessageStateHolder = userMessageStateHolder, )