diff --git a/README.md b/README.md index 6e2475afa..1c0b0cd32 100644 --- a/README.md +++ b/README.md @@ -97,18 +97,16 @@ TimetableScreen ----> timetableScreenPresenter -> sessionsRepository ```kotlin @Composable fun timetableScreenPresenter( - events: Flow, + events: EventEmitter, sessionsRepository: SessionsRepository = localSessionsRepository(), ): TimetableScreenUiState = providePresenterDefaults { userMessageStateHolder -> ... - SafeLaunchedEffect(Unit) { - events.collect { event -> - when (event) { - is Bookmark -> { - sessionsRepository.toggleBookmark(event.timetableItem.id) - } - ... + EventEffect(Unit) { event -> + when (event) { + is Bookmark -> { + sessionsRepository.toggleBookmark(event.timetableItem.id) } + ... } } ... @@ -176,7 +174,7 @@ SessionsRepository ----> timetableScreenPresenter ```kotlin @Composable fun timetableScreenPresenter( - events: Flow, + events: EventEmitter, sessionsRepository: SessionsRepository = localSessionsRepository(), ): TimetableScreenUiState = providePresenterDefaults { userMessageStateHolder -> // Sessions are updated in the timetable() function @@ -189,10 +187,8 @@ fun timetableScreenPresenter( ), ) ... - SafeLaunchedEffect(Unit) { - events.collect { event -> - ... - } + EventEffect(events) { event -> + ... } TimetableScreenUiState( contentUiState = timetableUiState, diff --git a/core/common/src/commonMain/kotlin/io/github/droidkaigi/confsched/compose/EventEmitter.kt b/core/common/src/commonMain/kotlin/io/github/droidkaigi/confsched/compose/EventEmitter.kt deleted file mode 100644 index 2d1da8578..000000000 --- a/core/common/src/commonMain/kotlin/io/github/droidkaigi/confsched/compose/EventEmitter.kt +++ /dev/null @@ -1,14 +0,0 @@ -package io.github.droidkaigi.confsched.compose - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import kotlinx.coroutines.flow.MutableSharedFlow - -typealias EventEmitter = MutableSharedFlow - -@Composable -fun rememberEventEmitter(): EventEmitter { - return remember { - MutableSharedFlow(extraBufferCapacity = 20) - } -} diff --git a/core/common/src/commonMain/kotlin/io/github/droidkaigi/confsched/compose/EventFlow.kt b/core/common/src/commonMain/kotlin/io/github/droidkaigi/confsched/compose/EventFlow.kt new file mode 100644 index 000000000..d1211e059 --- /dev/null +++ b/core/common/src/commonMain/kotlin/io/github/droidkaigi/confsched/compose/EventFlow.kt @@ -0,0 +1,30 @@ +package io.github.droidkaigi.confsched.compose + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.launch + +typealias EventFlow = MutableSharedFlow + +@Composable +fun rememberEventFlow(): EventFlow { + return remember { + MutableSharedFlow(extraBufferCapacity = 20) + } +} + +@Composable +fun EventEffect( + eventFlow: EventFlow, + block: suspend CoroutineScope.(EVENT) -> Unit, +) { + SafeLaunchedEffect(eventFlow) { + eventFlow.collect { event -> + launch { + block(event) + } + } + } +} 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 e53f7c84e..7d970163d 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 @@ -20,7 +20,7 @@ import androidx.compose.ui.platform.testTag import androidx.navigation.NavGraphBuilder import androidx.navigation.compose.composable import conference_app_2024.feature.contributors.generated.resources.contributor_title -import io.github.droidkaigi.confsched.compose.rememberEventEmitter +import io.github.droidkaigi.confsched.compose.rememberEventFlow import io.github.droidkaigi.confsched.contributors.component.ContributorsItem import io.github.droidkaigi.confsched.droidkaigiui.SnackbarMessageEffect import io.github.droidkaigi.confsched.droidkaigiui.UserMessageStateHolder @@ -65,7 +65,7 @@ fun ContributorsScreen( modifier: Modifier = Modifier, isTopAppBarHidden: Boolean = false, ) { - val eventEmitter = rememberEventEmitter() + val eventEmitter = rememberEventFlow() val uiState = contributorsScreenPresenter( events = eventEmitter, ) 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 48b3a0f4b..93a73702b 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 @@ -3,23 +3,21 @@ package io.github.droidkaigi.confsched.contributors import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.rememberUpdatedState -import io.github.droidkaigi.confsched.compose.SafeLaunchedEffect +import io.github.droidkaigi.confsched.compose.EventEffect +import io.github.droidkaigi.confsched.compose.EventFlow import io.github.droidkaigi.confsched.droidkaigiui.providePresenterDefaults import io.github.droidkaigi.confsched.model.ContributorsRepository import io.github.droidkaigi.confsched.model.localContributorsRepository -import kotlinx.coroutines.flow.Flow sealed interface ContributorsScreenEvent @Composable fun contributorsScreenPresenter( - events: Flow, + events: EventFlow, contributorsRepository: ContributorsRepository = localContributorsRepository(), ): ContributorsUiState = providePresenterDefaults { userMessageStateHolder -> val contributors by rememberUpdatedState(contributorsRepository.contributors()) - SafeLaunchedEffect(Unit) { - events.collect { - } + EventEffect(events) { event -> } ContributorsUiState( contributors = contributors, diff --git a/feature/contributors/src/iosMain/kotlin/io/github/droidkaigi/confsched/contributors/ContributorsViewController.kt b/feature/contributors/src/iosMain/kotlin/io/github/droidkaigi/confsched/contributors/ContributorsViewController.kt index ad72f97b5..7c08ea9d0 100644 --- a/feature/contributors/src/iosMain/kotlin/io/github/droidkaigi/confsched/contributors/ContributorsViewController.kt +++ b/feature/contributors/src/iosMain/kotlin/io/github/droidkaigi/confsched/contributors/ContributorsViewController.kt @@ -1,5 +1,6 @@ package io.github.droidkaigi.confsched.contributors +import io.github.droidkaigi.confsched.compose.EventFlow import io.github.droidkaigi.confsched.data.Repositories import io.github.droidkaigi.confsched.droidkaigiui.composeViewController import io.github.droidkaigi.confsched.droidkaigiui.presenterStateFlow @@ -22,7 +23,7 @@ fun contributorsViewController( @Suppress("unused") fun contributorsScreenPresenterStateFlow( repositories: Map, Any>, - events: Flow, + events: EventFlow, ): Flow = presenterStateFlow( events = events, repositories = repositories, diff --git a/feature/eventmap/src/commonMain/kotlin/io/github/droidkaigi/confsched/eventmap/EventMapScreen.kt b/feature/eventmap/src/commonMain/kotlin/io/github/droidkaigi/confsched/eventmap/EventMapScreen.kt index 59524a3ff..df65afb04 100644 --- a/feature/eventmap/src/commonMain/kotlin/io/github/droidkaigi/confsched/eventmap/EventMapScreen.kt +++ b/feature/eventmap/src/commonMain/kotlin/io/github/droidkaigi/confsched/eventmap/EventMapScreen.kt @@ -29,7 +29,7 @@ import androidx.navigation.NavGraphBuilder import androidx.navigation.compose.composable import co.touchlab.kermit.Logger import conference_app_2024.feature.eventmap.generated.resources.eventmap -import io.github.droidkaigi.confsched.compose.rememberEventEmitter +import io.github.droidkaigi.confsched.compose.rememberEventFlow import io.github.droidkaigi.confsched.droidkaigiui.SnackbarMessageEffect import io.github.droidkaigi.confsched.droidkaigiui.UserMessageStateHolder import io.github.droidkaigi.confsched.droidkaigiui.component.AnimatedTextTopAppBar @@ -81,7 +81,7 @@ fun EventMapScreen( modifier: Modifier = Modifier, contentPadding: PaddingValues = PaddingValues(), ) { - val eventEmitter = rememberEventEmitter() + val eventEmitter = rememberEventFlow() val uiState = eventMapScreenPresenter( events = eventEmitter, ) diff --git a/feature/eventmap/src/commonMain/kotlin/io/github/droidkaigi/confsched/eventmap/EventMapScreenPresenter.kt b/feature/eventmap/src/commonMain/kotlin/io/github/droidkaigi/confsched/eventmap/EventMapScreenPresenter.kt index 6dba6e8c1..4ed588fa7 100644 --- a/feature/eventmap/src/commonMain/kotlin/io/github/droidkaigi/confsched/eventmap/EventMapScreenPresenter.kt +++ b/feature/eventmap/src/commonMain/kotlin/io/github/droidkaigi/confsched/eventmap/EventMapScreenPresenter.kt @@ -3,23 +3,21 @@ package io.github.droidkaigi.confsched.eventmap import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.rememberUpdatedState -import io.github.droidkaigi.confsched.compose.SafeLaunchedEffect +import io.github.droidkaigi.confsched.compose.EventEffect +import io.github.droidkaigi.confsched.compose.EventFlow import io.github.droidkaigi.confsched.droidkaigiui.providePresenterDefaults import io.github.droidkaigi.confsched.model.EventMapRepository import io.github.droidkaigi.confsched.model.localEventMapRepository -import kotlinx.coroutines.flow.Flow sealed interface EventMapScreenEvent @Composable fun eventMapScreenPresenter( - events: Flow, + events: EventFlow, eventMapRepository: EventMapRepository = localEventMapRepository(), ): EventMapUiState = providePresenterDefaults { userMessageStateHolder -> val eventMap by rememberUpdatedState(eventMapRepository.eventMapEvents()) - SafeLaunchedEffect(Unit) { - events.collect { - } + EventEffect(events) { event -> } EventMapUiState( eventMap = eventMap, diff --git a/feature/favorites/src/commonMain/kotlin/io/github/droidkaigi/confsched/favorites/FavoritesScreen.kt b/feature/favorites/src/commonMain/kotlin/io/github/droidkaigi/confsched/favorites/FavoritesScreen.kt index d93089261..97b384a5a 100644 --- a/feature/favorites/src/commonMain/kotlin/io/github/droidkaigi/confsched/favorites/FavoritesScreen.kt +++ b/feature/favorites/src/commonMain/kotlin/io/github/droidkaigi/confsched/favorites/FavoritesScreen.kt @@ -25,8 +25,8 @@ import androidx.navigation.NavGraph.Companion.findStartDestination import androidx.navigation.NavGraphBuilder import androidx.navigation.compose.composable import conference_app_2024.feature.favorites.generated.resources.favorite -import io.github.droidkaigi.confsched.compose.EventEmitter -import io.github.droidkaigi.confsched.compose.rememberEventEmitter +import io.github.droidkaigi.confsched.compose.EventFlow +import io.github.droidkaigi.confsched.compose.rememberEventFlow import io.github.droidkaigi.confsched.designsystem.theme.KaigiTheme import io.github.droidkaigi.confsched.droidkaigiui.SnackbarMessageEffect import io.github.droidkaigi.confsched.droidkaigiui.UserMessageStateHolder @@ -79,8 +79,8 @@ fun FavoritesScreen( onTimetableItemClick: (TimetableItem) -> Unit, modifier: Modifier = Modifier, contentPadding: PaddingValues = PaddingValues(), - eventEmitter: EventEmitter = rememberEventEmitter(), - uiState: FavoritesScreenUiState = favoritesScreenPresenter(events = eventEmitter), + eventFlow: EventFlow = rememberEventFlow(), + uiState: FavoritesScreenUiState = favoritesScreenPresenter(events = eventFlow), ) { val snackbarHostState = remember { SnackbarHostState() } @@ -93,16 +93,16 @@ fun FavoritesScreen( snackbarHostState = snackbarHostState, onTimetableItemClick = onTimetableItemClick, onAllFilterChipClick = { - eventEmitter.tryEmit(FavoritesScreenEvent.AllFilter) + eventFlow.tryEmit(FavoritesScreenEvent.AllFilter) }, onDay1FilterChipClick = { - eventEmitter.tryEmit(FavoritesScreenEvent.Day1Filter) + eventFlow.tryEmit(FavoritesScreenEvent.Day1Filter) }, onDay2FilterChipClick = { - eventEmitter.tryEmit(FavoritesScreenEvent.Day2Filter) + eventFlow.tryEmit(FavoritesScreenEvent.Day2Filter) }, onBookmarkClick = { timetableItem -> - eventEmitter.tryEmit(FavoritesScreenEvent.Bookmark(timetableItem)) + eventFlow.tryEmit(FavoritesScreenEvent.Bookmark(timetableItem)) }, contentPadding = contentPadding, modifier = modifier, diff --git a/feature/favorites/src/commonMain/kotlin/io/github/droidkaigi/confsched/favorites/FavoritesScreenPresenter.kt b/feature/favorites/src/commonMain/kotlin/io/github/droidkaigi/confsched/favorites/FavoritesScreenPresenter.kt index 20f68ff18..f06ddbac0 100644 --- a/feature/favorites/src/commonMain/kotlin/io/github/droidkaigi/confsched/favorites/FavoritesScreenPresenter.kt +++ b/feature/favorites/src/commonMain/kotlin/io/github/droidkaigi/confsched/favorites/FavoritesScreenPresenter.kt @@ -6,7 +6,8 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberUpdatedState import androidx.compose.runtime.setValue -import io.github.droidkaigi.confsched.compose.SafeLaunchedEffect +import io.github.droidkaigi.confsched.compose.EventEffect +import io.github.droidkaigi.confsched.compose.EventFlow import io.github.droidkaigi.confsched.droidkaigiui.providePresenterDefaults import io.github.droidkaigi.confsched.favorites.FavoritesScreenEvent.AllFilter import io.github.droidkaigi.confsched.favorites.FavoritesScreenEvent.Bookmark @@ -26,7 +27,6 @@ import kotlinx.collections.immutable.PersistentSet import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toPersistentMap import kotlinx.collections.immutable.toPersistentSet -import kotlinx.coroutines.flow.Flow sealed interface FavoritesScreenEvent { data class Bookmark(val timetableItem: TimetableItem) : FavoritesScreenEvent @@ -38,7 +38,7 @@ sealed interface FavoritesScreenEvent { @Composable fun favoritesScreenPresenter( - events: Flow, + events: EventFlow, sessionsRepository: SessionsRepository = localSessionsRepository(), ): FavoritesScreenUiState = providePresenterDefaults { userMessageStateHolder -> val favoriteSessions by rememberUpdatedState( @@ -56,33 +56,32 @@ fun favoritesScreenPresenter( ), ) - SafeLaunchedEffect(Unit) { - events.collect { event -> - when (event) { - is Bookmark -> { - sessionsRepository.toggleBookmark(event.timetableItem.id) - } + EventEffect(events) { event -> + when (event) { + is Bookmark -> { + sessionsRepository.toggleBookmark(event.timetableItem.id) + } - AllFilter -> { - allFilterSelected = true - currentDayFilters = emptySet() - } + AllFilter -> { + allFilterSelected = true + currentDayFilters = emptySet() + } - Day1Filter, Day2Filter -> { - allFilterSelected = false + Day1Filter, Day2Filter -> { + allFilterSelected = false - val dayType = if (event is Day1Filter) { - ConferenceDay1 - } else { - ConferenceDay2 - } + val dayType = if (event is Day1Filter) { + ConferenceDay1 + } else { + ConferenceDay2 + } - currentDayFilters = if (currentDayFilters.contains(dayType) && currentDayFilters.size >= 2) { + currentDayFilters = + if (currentDayFilters.contains(dayType) && currentDayFilters.size >= 2) { currentDayFilters - dayType } else { currentDayFilters + dayType } - } } } } diff --git a/feature/main/src/commonMain/kotlin/io/github/droidkaigi/confsched/main/MainScreen.kt b/feature/main/src/commonMain/kotlin/io/github/droidkaigi/confsched/main/MainScreen.kt index 13cd1fe23..5280c94c1 100644 --- a/feature/main/src/commonMain/kotlin/io/github/droidkaigi/confsched/main/MainScreen.kt +++ b/feature/main/src/commonMain/kotlin/io/github/droidkaigi/confsched/main/MainScreen.kt @@ -54,8 +54,8 @@ import conference_app_2024.feature.main.generated.resources.timetable import dev.chrisbanes.haze.HazeState import dev.chrisbanes.haze.HazeStyle import dev.chrisbanes.haze.haze -import io.github.droidkaigi.confsched.compose.EventEmitter -import io.github.droidkaigi.confsched.compose.rememberEventEmitter +import io.github.droidkaigi.confsched.compose.EventFlow +import io.github.droidkaigi.confsched.compose.rememberEventFlow import io.github.droidkaigi.confsched.designsystem.DesignSystemRes import io.github.droidkaigi.confsched.droidkaigiui.SnackbarMessageEffect import io.github.droidkaigi.confsched.droidkaigiui.UserMessageStateHolder @@ -112,8 +112,8 @@ fun MainScreen( windowSize: WindowSizeClass, mainNestedGraphStateHolder: MainNestedGraphStateHolder, mainNestedNavGraph: NavGraphBuilder.(NavController, PaddingValues) -> Unit, - eventEmitter: EventEmitter = rememberEventEmitter(), - uiState: MainScreenUiState = mainScreenPresenter(eventEmitter), + eventFlow: EventFlow = rememberEventFlow(), + uiState: MainScreenUiState = mainScreenPresenter(eventFlow), ) { val snackbarHostState = remember { SnackbarHostState() } diff --git a/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/ProfileCardScreen.kt b/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/ProfileCardScreen.kt index 24345525d..a02e32846 100644 --- a/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/ProfileCardScreen.kt +++ b/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/ProfileCardScreen.kt @@ -95,8 +95,8 @@ import conference_app_2024.feature.profilecard.generated.resources.profile_card_ import conference_app_2024.feature.profilecard.generated.resources.select_theme import conference_app_2024.feature.profilecard.generated.resources.share import conference_app_2024.feature.profilecard.generated.resources.share_description -import io.github.droidkaigi.confsched.compose.EventEmitter -import io.github.droidkaigi.confsched.compose.rememberEventEmitter +import io.github.droidkaigi.confsched.compose.EventFlow +import io.github.droidkaigi.confsched.compose.rememberEventFlow import io.github.droidkaigi.confsched.designsystem.theme.LocalProfileCardTheme import io.github.droidkaigi.confsched.designsystem.theme.ProfileCardTheme import io.github.droidkaigi.confsched.designsystem.theme.ProvideProfileCardTheme @@ -199,7 +199,7 @@ fun ProfileCardScreen( contentPadding = contentPadding, onClickShareProfileCard = onClickShareProfileCard, modifier = modifier, - eventEmitter = rememberEventEmitter(), + eventFlow = rememberEventFlow(), ) } @@ -209,8 +209,8 @@ internal fun ProfileCardScreen( contentPadding: PaddingValues, onClickShareProfileCard: (String, ImageBitmap) -> Unit, modifier: Modifier = Modifier, - eventEmitter: EventEmitter = rememberEventEmitter(), - uiState: ProfileCardScreenState = profileCardScreenPresenter(eventEmitter), + eventFlow: EventFlow = rememberEventFlow(), + uiState: ProfileCardScreenState = profileCardScreenPresenter(eventFlow), ) { val snackbarHostState = remember { SnackbarHostState() } val layoutDirection = LocalLayoutDirection.current @@ -286,19 +286,19 @@ internal fun ProfileCardScreen( profileCardError = uiState.cardError, scrollBehavior = scrollBehavior, onChangeNickname = { - eventEmitter.tryEmit(EditScreenEvent.OnChangeNickname(it)) + eventFlow.tryEmit(EditScreenEvent.OnChangeNickname(it)) }, onChangeOccupation = { - eventEmitter.tryEmit(EditScreenEvent.OnChangeOccupation(it)) + eventFlow.tryEmit(EditScreenEvent.OnChangeOccupation(it)) }, onChangeLink = { - eventEmitter.tryEmit(EditScreenEvent.OnChangeLink(it)) + eventFlow.tryEmit(EditScreenEvent.OnChangeLink(it)) }, onChangeImage = { - eventEmitter.tryEmit(EditScreenEvent.OnChangeImage(it)) + eventFlow.tryEmit(EditScreenEvent.OnChangeImage(it)) }, onClickCreate = { - eventEmitter.tryEmit(EditScreenEvent.Create(it)) + eventFlow.tryEmit(EditScreenEvent.Create(it)) }, contentPadding = padding, ) @@ -312,7 +312,7 @@ internal fun ProfileCardScreen( uiState = uiState.cardUiState, scrollBehavior = scrollBehavior, onClickEdit = { - eventEmitter.tryEmit(CardScreenEvent.Edit) + eventFlow.tryEmit(CardScreenEvent.Edit) }, onClickShareProfileCard = { imageBitmap -> onClickShareProfileCard(shareText, imageBitmap) diff --git a/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/ProfileCardScreenPresenter.kt b/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/ProfileCardScreenPresenter.kt index 0bea07d6c..7ae645d19 100644 --- a/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/ProfileCardScreenPresenter.kt +++ b/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/ProfileCardScreenPresenter.kt @@ -12,13 +12,14 @@ import conference_app_2024.feature.profilecard.generated.resources.image import conference_app_2024.feature.profilecard.generated.resources.link import conference_app_2024.feature.profilecard.generated.resources.nickname import conference_app_2024.feature.profilecard.generated.resources.occupation +import io.github.droidkaigi.confsched.compose.EventEffect +import io.github.droidkaigi.confsched.compose.EventFlow import io.github.droidkaigi.confsched.compose.SafeLaunchedEffect import io.github.droidkaigi.confsched.droidkaigiui.providePresenterDefaults import io.github.droidkaigi.confsched.model.ProfileCard import io.github.droidkaigi.confsched.model.ProfileCardRepository import io.github.droidkaigi.confsched.model.localProfileCardRepository import io.github.droidkaigi.confsched.profilecard.ProfileCardUiType.Card -import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.launch import org.jetbrains.compose.resources.stringResource @@ -79,7 +80,7 @@ private fun ProfileCard.toCardUiState(): ProfileCardUiState.Card? { @Composable internal fun profileCardScreenPresenter( - events: Flow, + events: EventFlow, repository: ProfileCardRepository = localProfileCardRepository(), ): ProfileCardScreenState = providePresenterDefaults { userMessageStateHolder -> val nicknameValidationErrorString = stringResource( @@ -115,59 +116,57 @@ internal fun profileCardScreenPresenter( } } - SafeLaunchedEffect(Unit) { - events.collect { event -> - when (event) { - is CardScreenEvent.Edit -> { - isLoading = true - launch { - userMessageStateHolder.showMessage("Edit") - } - uiType = ProfileCardUiType.Edit - isLoading = false + EventEffect(events) { event -> + when (event) { + is CardScreenEvent.Edit -> { + isLoading = true + launch { + userMessageStateHolder.showMessage("Edit") } + uiType = ProfileCardUiType.Edit + isLoading = false + } - is EditScreenEvent.Create -> { - isLoading = true - launch { - userMessageStateHolder.showMessage("Create Profile Card") - } - repository.save(event.profileCard) - uiType = Card - isLoading = false + is EditScreenEvent.Create -> { + isLoading = true + launch { + userMessageStateHolder.showMessage("Create Profile Card") } + repository.save(event.profileCard) + uiType = Card + isLoading = false + } - is EditScreenEvent.SelectImage -> { - isLoading = true - launch { - userMessageStateHolder.showMessage("Select Image") - } - isLoading = false + is EditScreenEvent.SelectImage -> { + isLoading = true + launch { + userMessageStateHolder.showMessage("Select Image") } + isLoading = false + } - is EditScreenEvent.OnChangeNickname -> { - cardError = cardError.copy( - nicknameError = if (event.nickname.isEmpty()) nicknameValidationErrorString else "", - ) - } + is EditScreenEvent.OnChangeNickname -> { + cardError = cardError.copy( + nicknameError = if (event.nickname.isEmpty()) nicknameValidationErrorString else "", + ) + } - is EditScreenEvent.OnChangeOccupation -> { - cardError = cardError.copy( - occupationError = if (event.occupation.isEmpty()) occupationValidationErrorString else "", - ) - } + is EditScreenEvent.OnChangeOccupation -> { + cardError = cardError.copy( + occupationError = if (event.occupation.isEmpty()) occupationValidationErrorString else "", + ) + } - is EditScreenEvent.OnChangeLink -> { - cardError = cardError.copy( - linkError = if (event.link.isEmpty()) linkValidationErrorString else "", - ) - } + is EditScreenEvent.OnChangeLink -> { + cardError = cardError.copy( + linkError = if (event.link.isEmpty()) linkValidationErrorString else "", + ) + } - is EditScreenEvent.OnChangeImage -> { - cardError = cardError.copy( - imageError = if (event.image.isEmpty()) imageValidationErrorString else "", - ) - } + is EditScreenEvent.OnChangeImage -> { + cardError = cardError.copy( + imageError = if (event.image.isEmpty()) imageValidationErrorString else "", + ) } } } diff --git a/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/SearchScreen.kt b/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/SearchScreen.kt index cf291984b..c02921fe9 100644 --- a/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/SearchScreen.kt +++ b/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/SearchScreen.kt @@ -18,8 +18,8 @@ import androidx.compose.ui.unit.dp import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.compose.composable -import io.github.droidkaigi.confsched.compose.EventEmitter -import io.github.droidkaigi.confsched.compose.rememberEventEmitter +import io.github.droidkaigi.confsched.compose.EventFlow +import io.github.droidkaigi.confsched.compose.rememberEventFlow import io.github.droidkaigi.confsched.designsystem.theme.KaigiTheme import io.github.droidkaigi.confsched.droidkaigiui.SnackbarMessageEffect import io.github.droidkaigi.confsched.droidkaigiui.UserMessageStateHolder @@ -69,8 +69,8 @@ fun SearchScreen( onTimetableItemClick: (TimetableItem) -> Unit, onBackClick: () -> Unit, modifier: Modifier = Modifier, - eventEmitter: EventEmitter = rememberEventEmitter(), - uiState: SearchScreenUiState = searchScreenPresenter(eventEmitter), + eventFlow: EventFlow = rememberEventFlow(), + uiState: SearchScreenUiState = searchScreenPresenter(eventFlow), ) { val snackbarHostState = remember { SnackbarHostState() } @@ -82,13 +82,13 @@ fun SearchScreen( SearchScreen( uiState = uiState, onTimetableItemClick = onTimetableItemClick, - onTimetableItemBookmark = { eventEmitter.tryEmit(SearchScreenEvent.Bookmark(it)) }, - onSearchWordChanged = { eventEmitter.tryEmit(SearchScreenEvent.UpdateSearchWord(it)) }, - onClearSearchWordClick = { eventEmitter.tryEmit(SearchScreenEvent.ClearSearchWord) }, - onSelectDay = { eventEmitter.tryEmit(SearchScreenEvent.SelectDay(it)) }, - onSelectSessionType = { eventEmitter.tryEmit(SearchScreenEvent.SelectSessionType(it)) }, - onSelectCategory = { eventEmitter.tryEmit(SearchScreenEvent.SelectCategory(it)) }, - onSelectLanguage = { eventEmitter.tryEmit(SearchScreenEvent.SelectLanguage(it)) }, + onTimetableItemBookmark = { eventFlow.tryEmit(SearchScreenEvent.Bookmark(it)) }, + onSearchWordChanged = { eventFlow.tryEmit(SearchScreenEvent.UpdateSearchWord(it)) }, + onClearSearchWordClick = { eventFlow.tryEmit(SearchScreenEvent.ClearSearchWord) }, + onSelectDay = { eventFlow.tryEmit(SearchScreenEvent.SelectDay(it)) }, + onSelectSessionType = { eventFlow.tryEmit(SearchScreenEvent.SelectSessionType(it)) }, + onSelectCategory = { eventFlow.tryEmit(SearchScreenEvent.SelectCategory(it)) }, + onSelectLanguage = { eventFlow.tryEmit(SearchScreenEvent.SelectLanguage(it)) }, onBackClick = onBackClick, modifier = modifier, ) diff --git a/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/SearchScreenPresenter.kt b/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/SearchScreenPresenter.kt index 8e1874602..877b7609b 100644 --- a/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/SearchScreenPresenter.kt +++ b/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/SearchScreenPresenter.kt @@ -8,7 +8,8 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberUpdatedState import androidx.compose.runtime.setValue -import io.github.droidkaigi.confsched.compose.SafeLaunchedEffect +import io.github.droidkaigi.confsched.compose.EventEffect +import io.github.droidkaigi.confsched.compose.EventFlow import io.github.droidkaigi.confsched.droidkaigiui.providePresenterDefaults import io.github.droidkaigi.confsched.model.DroidKaigi2024Day import io.github.droidkaigi.confsched.model.Filters @@ -30,7 +31,6 @@ import io.github.droidkaigi.confsched.sessions.component.SearchFilterUiState import io.github.droidkaigi.confsched.sessions.section.TimetableListUiState import io.github.takahirom.rin.rememberRetained import kotlinx.collections.immutable.toPersistentMap -import kotlinx.coroutines.flow.Flow sealed interface SearchScreenEvent { data class Bookmark(val timetableItem: TimetableItem) : SearchScreenEvent @@ -44,7 +44,7 @@ sealed interface SearchScreenEvent { @Composable fun searchScreenPresenter( - events: Flow, + events: EventFlow, sessionsRepository: SessionsRepository = localSessionsRepository(), ): SearchScreenUiState = providePresenterDefaults { userMessageStateHolder -> val sessions by rememberUpdatedState(sessionsRepository.timetable()) @@ -101,51 +101,49 @@ fun searchScreenPresenter( ), ) - SafeLaunchedEffect(Unit) { - events.collect { event -> - when (event) { - is Bookmark -> { - sessionsRepository.toggleBookmark(event.timetableItem.id) - } + EventEffect(events) { event -> + when (event) { + is Bookmark -> { + sessionsRepository.toggleBookmark(event.timetableItem.id) + } - is UpdateSearchWord -> { - searchWord = event.word - } + is UpdateSearchWord -> { + searchWord = event.word + } - is ClearSearchWord -> { - searchWord = "" - } + is ClearSearchWord -> { + searchWord = "" + } - is SelectDay -> { - if (selectedDays.contains(event.day)) { - selectedDays.remove(event.day) - } else { - selectedDays.add(event.day) - } + is SelectDay -> { + if (selectedDays.contains(event.day)) { + selectedDays.remove(event.day) + } else { + selectedDays.add(event.day) } + } - is SelectCategory -> { - if (selectedCategories.contains(event.category)) { - selectedCategories.remove(event.category) - } else { - selectedCategories.add(event.category) - } + is SelectCategory -> { + if (selectedCategories.contains(event.category)) { + selectedCategories.remove(event.category) + } else { + selectedCategories.add(event.category) } + } - is SelectSessionType -> { - if (selectedSessionTypes.contains(event.sessionType)) { - selectedSessionTypes.remove(event.sessionType) - } else { - selectedSessionTypes.add(event.sessionType) - } + is SelectSessionType -> { + if (selectedSessionTypes.contains(event.sessionType)) { + selectedSessionTypes.remove(event.sessionType) + } else { + selectedSessionTypes.add(event.sessionType) } + } - is SelectLanguage -> { - if (selectedLanguages.contains(event.language)) { - selectedLanguages.remove(event.language) - } else { - selectedLanguages.add(event.language) - } + is SelectLanguage -> { + if (selectedLanguages.contains(event.language)) { + selectedLanguages.remove(event.language) + } else { + selectedLanguages.add(event.language) } } } diff --git a/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/TimetableItemDetailPresenter.kt b/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/TimetableItemDetailPresenter.kt index 08c29dcfa..1e0326438 100644 --- a/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/TimetableItemDetailPresenter.kt +++ b/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/TimetableItemDetailPresenter.kt @@ -10,6 +10,8 @@ import androidx.compose.runtime.setValue import co.touchlab.kermit.Logger import conference_app_2024.feature.sessions.generated.resources.bookmarked_successfully import conference_app_2024.feature.sessions.generated.resources.view_bookmark_list +import io.github.droidkaigi.confsched.compose.EventEffect +import io.github.droidkaigi.confsched.compose.EventFlow import io.github.droidkaigi.confsched.compose.SafeLaunchedEffect import io.github.droidkaigi.confsched.droidkaigiui.UserMessageResult.ActionPerformed import io.github.droidkaigi.confsched.droidkaigiui.providePresenterDefaults @@ -26,7 +28,6 @@ import io.github.droidkaigi.confsched.sessions.TimetableItemDetailEvent.SelectDe import io.github.droidkaigi.confsched.sessions.TimetableItemDetailScreenUiState.Loaded import io.github.droidkaigi.confsched.sessions.TimetableItemDetailScreenUiState.Loading import io.github.takahirom.rin.rememberRetained -import kotlinx.coroutines.flow.SharedFlow import org.jetbrains.compose.resources.stringResource sealed interface TimetableItemDetailEvent { @@ -37,7 +38,7 @@ sealed interface TimetableItemDetailEvent { @Composable fun timetableItemDetailPresenter( - events: SharedFlow, + events: EventFlow, sessionsRepository: SessionsRepository = localSessionsRepository(), timetableItemIdArg: String = rememberNavigationArgument( key = timetableItemDetailScreenRouteItemIdParameterName, @@ -54,34 +55,32 @@ fun timetableItemDetailPresenter( val bookmarkedSuccessfullyString = stringResource(SessionsRes.string.bookmarked_successfully) val viewBookmarkListString = stringResource(SessionsRes.string.view_bookmark_list) - SafeLaunchedEffect(Unit) { - events.collect { event -> - when (event) { - is Bookmark -> { - val timetableItemWithBookmark = timetableItemStateWithBookmark - val timetableItem = - timetableItemWithBookmark?.first ?: return@collect - sessionsRepository.toggleBookmark(timetableItem.id) - val oldBookmarked = timetableItemWithBookmark.second - if (!oldBookmarked) { - val result = userMessageStateHolder.showMessage( - message = bookmarkedSuccessfullyString, - actionLabel = viewBookmarkListString, - duration = Short, - ) - if (result == ActionPerformed) { - shouldGoToFavoriteList = true - } + EventEffect(events) { event -> + when (event) { + is Bookmark -> { + val timetableItemWithBookmark = timetableItemStateWithBookmark + val timetableItem = + timetableItemWithBookmark?.first ?: return@EventEffect + sessionsRepository.toggleBookmark(timetableItem.id) + val oldBookmarked = timetableItemWithBookmark.second + if (!oldBookmarked) { + val result = userMessageStateHolder.showMessage( + message = bookmarkedSuccessfullyString, + actionLabel = viewBookmarkListString, + duration = Short, + ) + if (result == ActionPerformed) { + shouldGoToFavoriteList = true } } + } - is SelectDescriptionLanguage -> { - selectedDescriptionLanguage = event.language - } + is SelectDescriptionLanguage -> { + selectedDescriptionLanguage = event.language + } - is FavoriteListNavigated -> { - shouldGoToFavoriteList = false - } + is FavoriteListNavigated -> { + shouldGoToFavoriteList = false } } } diff --git a/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/TimetableItemDetailScreen.kt b/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/TimetableItemDetailScreen.kt index 9d9cdde45..819d885d8 100644 --- a/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/TimetableItemDetailScreen.kt +++ b/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/TimetableItemDetailScreen.kt @@ -28,8 +28,8 @@ import androidx.compose.ui.platform.testTag import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.compose.composable -import io.github.droidkaigi.confsched.compose.EventEmitter -import io.github.droidkaigi.confsched.compose.rememberEventEmitter +import io.github.droidkaigi.confsched.compose.EventFlow +import io.github.droidkaigi.confsched.compose.rememberEventFlow import io.github.droidkaigi.confsched.designsystem.component.LoadingText import io.github.droidkaigi.confsched.designsystem.theme.KaigiTheme import io.github.droidkaigi.confsched.designsystem.theme.ProvideRoomTheme @@ -92,9 +92,9 @@ fun TimetableItemDetailScreen( onCalendarRegistrationClick: (TimetableItem) -> Unit, onShareClick: (TimetableItem) -> Unit, onFavoriteListClick: () -> Unit, - eventEmitter: EventEmitter = rememberEventEmitter(), + eventFlow: EventFlow = rememberEventFlow(), uiState: TimetableItemDetailScreenUiState = timetableItemDetailPresenter( - events = eventEmitter, + events = eventFlow, ), ) { val snackbarHostState = remember { SnackbarHostState() } @@ -105,7 +105,7 @@ fun TimetableItemDetailScreen( LaunchedEffect(uiState is Loaded && uiState.shouldGoToFavoriteList) { if (uiState is Loaded && uiState.shouldGoToFavoriteList) { - eventEmitter.tryEmit(TimetableItemDetailEvent.FavoriteListNavigated) + eventFlow.tryEmit(TimetableItemDetailEvent.FavoriteListNavigated) onFavoriteListClick() } } @@ -114,13 +114,13 @@ fun TimetableItemDetailScreen( uiState = uiState, onNavigationIconClick = onNavigationIconClick, onBookmarkClick = { - eventEmitter.tryEmit(TimetableItemDetailEvent.Bookmark(it)) + eventFlow.tryEmit(TimetableItemDetailEvent.Bookmark(it)) }, onLinkClick = onLinkClick, onCalendarRegistrationClick = onCalendarRegistrationClick, onShareClick = onShareClick, onSelectedLanguage = { - eventEmitter.tryEmit(TimetableItemDetailEvent.SelectDescriptionLanguage(it)) + eventFlow.tryEmit(TimetableItemDetailEvent.SelectDescriptionLanguage(it)) }, snackbarHostState = snackbarHostState, ) diff --git a/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/TimetableScreen.kt b/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/TimetableScreen.kt index 0fb901ed9..a4d521ff1 100644 --- a/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/TimetableScreen.kt +++ b/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/TimetableScreen.kt @@ -41,8 +41,8 @@ import androidx.navigation.compose.composable import conference_app_2024.feature.sessions.generated.resources.ic_grid_view import conference_app_2024.feature.sessions.generated.resources.ic_view_timeline import conference_app_2024.feature.sessions.generated.resources.timetable -import io.github.droidkaigi.confsched.compose.EventEmitter -import io.github.droidkaigi.confsched.compose.rememberEventEmitter +import io.github.droidkaigi.confsched.compose.EventFlow +import io.github.droidkaigi.confsched.compose.rememberEventFlow import io.github.droidkaigi.confsched.designsystem.theme.KaigiTheme import io.github.droidkaigi.confsched.droidkaigiui.SnackbarMessageEffect import io.github.droidkaigi.confsched.droidkaigiui.UserMessageStateHolder @@ -98,9 +98,9 @@ fun TimetableScreen( onTimetableItemClick: (TimetableItem) -> Unit, modifier: Modifier = Modifier, contentPadding: PaddingValues = PaddingValues(), - eventEmitter: EventEmitter = rememberEventEmitter(), + eventFlow: EventFlow = rememberEventFlow(), uiState: TimetableScreenUiState = timetableScreenPresenter( - events = eventEmitter, + events = eventFlow, ), ) { val snackbarHostState = remember { SnackbarHostState() } @@ -115,10 +115,10 @@ fun TimetableScreen( onSearchClick = onSearchClick, onTimetableItemClick = onTimetableItemClick, onBookmarkClick = { item, bookmarked -> - eventEmitter.tryEmit(TimetableScreenEvent.Bookmark(item, bookmarked)) + eventFlow.tryEmit(TimetableScreenEvent.Bookmark(item, bookmarked)) }, onTimetableUiChangeClick = { - eventEmitter.tryEmit(TimetableScreenEvent.UiTypeChange) + eventFlow.tryEmit(TimetableScreenEvent.UiTypeChange) }, contentPadding = contentPadding, modifier = modifier, diff --git a/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/TimetableScreenPresenter.kt b/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/TimetableScreenPresenter.kt index fd9ca3fa4..401ade996 100644 --- a/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/TimetableScreenPresenter.kt +++ b/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/TimetableScreenPresenter.kt @@ -8,7 +8,8 @@ import androidx.compose.runtime.rememberUpdatedState import androidx.compose.runtime.setValue import androidx.lifecycle.Lifecycle import androidx.lifecycle.compose.LifecycleEventEffect -import io.github.droidkaigi.confsched.compose.SafeLaunchedEffect +import io.github.droidkaigi.confsched.compose.EventEffect +import io.github.droidkaigi.confsched.compose.EventFlow import io.github.droidkaigi.confsched.droidkaigiui.compositionlocal.LocalClock import io.github.droidkaigi.confsched.droidkaigiui.providePresenterDefaults import io.github.droidkaigi.confsched.model.DroidKaigi2024Day @@ -27,7 +28,6 @@ import io.github.droidkaigi.confsched.sessions.section.TimetableListUiState import io.github.droidkaigi.confsched.sessions.section.TimetableUiState import io.github.takahirom.rin.rememberRetained import kotlinx.collections.immutable.toPersistentMap -import kotlinx.coroutines.flow.Flow sealed interface TimetableScreenEvent { data class Bookmark(val timetableItem: TimetableItem, val bookmarked: Boolean) : @@ -38,7 +38,7 @@ sealed interface TimetableScreenEvent { @Composable fun timetableScreenPresenter( - events: Flow, + events: EventFlow, sessionsRepository: SessionsRepository = localSessionsRepository(), ): TimetableScreenUiState = providePresenterDefaults { userMessageStateHolder -> val sessions by rememberUpdatedState(sessionsRepository.timetable()) @@ -55,21 +55,19 @@ fun timetableScreenPresenter( ), ) - SafeLaunchedEffect(Unit) { - events.collect { event -> - when (event) { - is Bookmark -> { - sessionsRepository.toggleBookmark(event.timetableItem.id) - } + EventEffect(events) { event -> + when (event) { + is Bookmark -> { + sessionsRepository.toggleBookmark(event.timetableItem.id) + } - UiTypeChange -> { - timetableUiType = - if (timetableUiType == TimetableUiType.List) { - Grid - } else { - TimetableUiType.List - } - } + UiTypeChange -> { + timetableUiType = + if (timetableUiType == TimetableUiType.List) { + Grid + } else { + TimetableUiType.List + } } } } diff --git a/feature/settings/src/commonMain/kotlin/io/github/droidkaigi/confsched/settings/SettingsScreen.kt b/feature/settings/src/commonMain/kotlin/io/github/droidkaigi/confsched/settings/SettingsScreen.kt index ff919d7af..56505d885 100644 --- a/feature/settings/src/commonMain/kotlin/io/github/droidkaigi/confsched/settings/SettingsScreen.kt +++ b/feature/settings/src/commonMain/kotlin/io/github/droidkaigi/confsched/settings/SettingsScreen.kt @@ -17,7 +17,7 @@ import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.navigation.NavGraphBuilder import androidx.navigation.compose.composable import conference_app_2024.feature.settings.generated.resources.settings_title -import io.github.droidkaigi.confsched.compose.rememberEventEmitter +import io.github.droidkaigi.confsched.compose.rememberEventFlow import io.github.droidkaigi.confsched.designsystem.theme.KaigiTheme import io.github.droidkaigi.confsched.droidkaigiui.SnackbarMessageEffect import io.github.droidkaigi.confsched.droidkaigiui.UserMessageStateHolder @@ -59,7 +59,7 @@ fun SettingsScreen( modifier: Modifier = Modifier, isTopAppBarHidden: Boolean = false, ) { - val eventEmitter = rememberEventEmitter() + val eventEmitter = rememberEventFlow() val uiState = settingsScreenPresenter(events = eventEmitter) val snackbarHostState = remember { SnackbarHostState() } diff --git a/feature/settings/src/commonMain/kotlin/io/github/droidkaigi/confsched/settings/SettingsScreenPresenter.kt b/feature/settings/src/commonMain/kotlin/io/github/droidkaigi/confsched/settings/SettingsScreenPresenter.kt index 4ace010d3..625e2e0e2 100644 --- a/feature/settings/src/commonMain/kotlin/io/github/droidkaigi/confsched/settings/SettingsScreenPresenter.kt +++ b/feature/settings/src/commonMain/kotlin/io/github/droidkaigi/confsched/settings/SettingsScreenPresenter.kt @@ -3,14 +3,14 @@ package io.github.droidkaigi.confsched.settings import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.rememberUpdatedState -import io.github.droidkaigi.confsched.compose.SafeLaunchedEffect +import io.github.droidkaigi.confsched.compose.EventEffect +import io.github.droidkaigi.confsched.compose.EventFlow import io.github.droidkaigi.confsched.droidkaigiui.providePresenterDefaults import io.github.droidkaigi.confsched.model.FontFamily import io.github.droidkaigi.confsched.model.Settings import io.github.droidkaigi.confsched.model.SettingsRepository import io.github.droidkaigi.confsched.model.localSettingsRepository import io.github.droidkaigi.confsched.settings.SettingsScreenEvent.SelectUseFontFamily -import kotlinx.coroutines.flow.Flow sealed interface SettingsScreenEvent { data class SelectUseFontFamily(val fontFamily: FontFamily) : SettingsScreenEvent @@ -18,20 +18,18 @@ sealed interface SettingsScreenEvent { @Composable fun settingsScreenPresenter( - events: Flow, + events: EventFlow, settingsRepository: SettingsRepository = localSettingsRepository(), ): SettingsUiState = providePresenterDefaults { userMessageStateHolder -> val settings by rememberUpdatedState(settingsRepository.settings()) - SafeLaunchedEffect(Unit) { - events.collect { event -> - when (event) { - is SelectUseFontFamily -> settingsRepository.save( - settings = Settings.Exists( - useFontFamily = event.fontFamily, - ), - ) - } + EventEffect(events) { event -> + when (event) { + is SelectUseFontFamily -> settingsRepository.save( + settings = Settings.Exists( + useFontFamily = event.fontFamily, + ), + ) } } SettingsUiState( diff --git a/feature/sponsors/src/commonMain/kotlin/io/github/droidkaigi/confsched/sponsors/SponsorsScreen.kt b/feature/sponsors/src/commonMain/kotlin/io/github/droidkaigi/confsched/sponsors/SponsorsScreen.kt index 750f59f29..5d8f8124d 100644 --- a/feature/sponsors/src/commonMain/kotlin/io/github/droidkaigi/confsched/sponsors/SponsorsScreen.kt +++ b/feature/sponsors/src/commonMain/kotlin/io/github/droidkaigi/confsched/sponsors/SponsorsScreen.kt @@ -17,7 +17,7 @@ import androidx.navigation.NavGraphBuilder import androidx.navigation.compose.composable import conference_app_2024.feature.sponsors.generated.resources.content_description_back import conference_app_2024.feature.sponsors.generated.resources.sponsor -import io.github.droidkaigi.confsched.compose.rememberEventEmitter +import io.github.droidkaigi.confsched.compose.rememberEventFlow import io.github.droidkaigi.confsched.designsystem.theme.KaigiTheme import io.github.droidkaigi.confsched.droidkaigiui.SnackbarMessageEffect import io.github.droidkaigi.confsched.droidkaigiui.UserMessageStateHolder @@ -74,7 +74,7 @@ fun SponsorsScreen( modifier: Modifier = Modifier, isTopAppBarHidden: Boolean = false, ) { - val eventEmitter = rememberEventEmitter() + val eventEmitter = rememberEventFlow() val uiState = sponsorsScreenPresenter(events = eventEmitter) val snackbarHostState = remember { SnackbarHostState() } diff --git a/feature/sponsors/src/commonMain/kotlin/io/github/droidkaigi/confsched/sponsors/SponsorsScreenPresenter.kt b/feature/sponsors/src/commonMain/kotlin/io/github/droidkaigi/confsched/sponsors/SponsorsScreenPresenter.kt index 4a3bed25a..98b2a6378 100644 --- a/feature/sponsors/src/commonMain/kotlin/io/github/droidkaigi/confsched/sponsors/SponsorsScreenPresenter.kt +++ b/feature/sponsors/src/commonMain/kotlin/io/github/droidkaigi/confsched/sponsors/SponsorsScreenPresenter.kt @@ -3,7 +3,8 @@ package io.github.droidkaigi.confsched.sponsors import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.rememberUpdatedState -import io.github.droidkaigi.confsched.compose.SafeLaunchedEffect +import io.github.droidkaigi.confsched.compose.EventEffect +import io.github.droidkaigi.confsched.compose.EventFlow import io.github.droidkaigi.confsched.droidkaigiui.providePresenterDefaults import io.github.droidkaigi.confsched.model.Plan.GOLD import io.github.droidkaigi.confsched.model.Plan.PLATINUM @@ -13,21 +14,19 @@ import io.github.droidkaigi.confsched.model.SponsorsRepository import io.github.droidkaigi.confsched.model.localSponsorsRepository import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.toPersistentList -import kotlinx.coroutines.flow.Flow sealed interface SponsorsScreenEvent @Composable fun sponsorsScreenPresenter( - events: Flow, + events: EventFlow, sponsorsRepository: SponsorsRepository = localSponsorsRepository(), ): SponsorsScreenUiState = providePresenterDefaults { userMessageStateHolder -> val sponsors by rememberUpdatedState(sponsorsRepository.sponsors()) val sponsorListUiState by rememberUpdatedState( sponsorList(sponsors = sponsors), ) - SafeLaunchedEffect(Unit) { - events.collect {} + EventEffect(events) { event -> } SponsorsScreenUiState( sponsorsListUiState = sponsorListUiState, diff --git a/feature/staff/src/commonMain/kotlin/io/github/droidkaigi/confsched/staff/StaffScreen.kt b/feature/staff/src/commonMain/kotlin/io/github/droidkaigi/confsched/staff/StaffScreen.kt index be2853728..46d386356 100644 --- a/feature/staff/src/commonMain/kotlin/io/github/droidkaigi/confsched/staff/StaffScreen.kt +++ b/feature/staff/src/commonMain/kotlin/io/github/droidkaigi/confsched/staff/StaffScreen.kt @@ -21,7 +21,7 @@ import androidx.compose.ui.platform.testTag import androidx.navigation.NavGraphBuilder import androidx.navigation.compose.composable import conference_app_2024.feature.staff.generated.resources.staff_title -import io.github.droidkaigi.confsched.compose.rememberEventEmitter +import io.github.droidkaigi.confsched.compose.rememberEventFlow import io.github.droidkaigi.confsched.designsystem.theme.KaigiTheme import io.github.droidkaigi.confsched.droidkaigiui.SnackbarMessageEffect import io.github.droidkaigi.confsched.droidkaigiui.UserMessageStateHolder @@ -71,7 +71,7 @@ fun StaffScreen( modifier: Modifier = Modifier, isTopAppBarHidden: Boolean = false, ) { - val eventEmitter = rememberEventEmitter() + val eventEmitter = rememberEventFlow() val uiState = staffScreenPresenter(events = eventEmitter) val snackbarHostState = remember { SnackbarHostState() } diff --git a/feature/staff/src/commonMain/kotlin/io/github/droidkaigi/confsched/staff/StaffScreenPresenter.kt b/feature/staff/src/commonMain/kotlin/io/github/droidkaigi/confsched/staff/StaffScreenPresenter.kt index 2b83460a7..56b67a0c7 100644 --- a/feature/staff/src/commonMain/kotlin/io/github/droidkaigi/confsched/staff/StaffScreenPresenter.kt +++ b/feature/staff/src/commonMain/kotlin/io/github/droidkaigi/confsched/staff/StaffScreenPresenter.kt @@ -3,22 +3,21 @@ package io.github.droidkaigi.confsched.staff import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.rememberUpdatedState -import io.github.droidkaigi.confsched.compose.SafeLaunchedEffect +import io.github.droidkaigi.confsched.compose.EventEffect +import io.github.droidkaigi.confsched.compose.EventFlow import io.github.droidkaigi.confsched.droidkaigiui.providePresenterDefaults import io.github.droidkaigi.confsched.model.StaffRepository import io.github.droidkaigi.confsched.model.localStaffRepository -import kotlinx.coroutines.flow.Flow sealed interface StaffScreenEvent @Composable fun staffScreenPresenter( - events: Flow, + events: EventFlow, staffRepository: StaffRepository = localStaffRepository(), ): StaffUiState = providePresenterDefaults { userMessageStateHolder -> val staff by rememberUpdatedState(staffRepository.staff()) - SafeLaunchedEffect(Unit) { - events.collect {} + EventEffect(events) { event -> } StaffUiState( staff = staff,