From 3d8ae8ed82d028341ae59b5a88cadd58851a7511 Mon Sep 17 00:00:00 2001 From: Ryo Takeuchi Date: Tue, 21 Nov 2023 20:30:18 +0900 Subject: [PATCH] =?UTF-8?q?:+1:=20=E3=83=88=E3=83=83=E3=83=97=E6=A9=9F?= =?UTF-8?q?=E8=83=BD=E3=83=A2=E3=82=B8=E3=83=A5=E3=83=BC=E3=83=AB=E3=82=92?= =?UTF-8?q?=20KMP=20=E3=81=A7=E5=86=8D=E6=A7=8B=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/club/nito/app/NitoApp.kt | 5 ++ .../java/club/nito/app/di/FeatureModules.kt | 8 ++ .../club/nito/core/ui/UiStateBuilder.kt | 79 +++++++++++++++++++ feature/top/build.gradle.kts | 3 + .../club/nito/feature/top/Platform.android.kt | 7 -- .../kotlin/club/nito/feature/top/TopEvent.kt | 6 -- .../kotlin/club/nito/feature/top/TopIntent.kt | 11 --- .../club/nito/feature/top/TopScreenUiState.kt | 16 ---- .../kotlin/club/nito/feature/top/Greeting.kt | 9 --- .../kotlin/club/nito/feature/top/Platform.kt | 7 -- .../kotlin/club/nito/feature/top/TopScreen.kt | 38 ++++----- .../club/nito/feature/top/TopScreenEvent.kt | 13 +++ .../club/nito/feature/top/TopScreenIntent.kt | 30 +++++++ .../club/nito/feature/top/TopScreenState.kt} | 39 ++++----- .../club/nito/feature/top/TopScreenUiState.kt | 33 ++++++++ .../component/ParticipantScheduleSection.kt | 0 .../nito/feature/top/di/topFeatureModule.kt | 15 ++++ .../kotlin/club/nito/feature/top/.gitkeep | 0 .../club/nito/feature/top/Platform.ios.kt | 9 --- 19 files changed, 222 insertions(+), 106 deletions(-) create mode 100644 app/android/src/main/java/club/nito/app/di/FeatureModules.kt create mode 100644 core/ui/src/commonMain/kotlin/club/nito/core/ui/UiStateBuilder.kt delete mode 100644 feature/top/src/androidMain/kotlin/club/nito/feature/top/Platform.android.kt delete mode 100644 feature/top/src/androidMain/kotlin/club/nito/feature/top/TopEvent.kt delete mode 100644 feature/top/src/androidMain/kotlin/club/nito/feature/top/TopIntent.kt delete mode 100644 feature/top/src/androidMain/kotlin/club/nito/feature/top/TopScreenUiState.kt delete mode 100644 feature/top/src/commonMain/kotlin/club/nito/feature/top/Greeting.kt delete mode 100644 feature/top/src/commonMain/kotlin/club/nito/feature/top/Platform.kt rename feature/top/src/{androidMain => commonMain}/kotlin/club/nito/feature/top/TopScreen.kt (70%) create mode 100644 feature/top/src/commonMain/kotlin/club/nito/feature/top/TopScreenEvent.kt create mode 100644 feature/top/src/commonMain/kotlin/club/nito/feature/top/TopScreenIntent.kt rename feature/top/src/{androidMain/kotlin/club/nito/feature/top/TopViewModel.kt => commonMain/kotlin/club/nito/feature/top/TopScreenState.kt} (61%) create mode 100644 feature/top/src/commonMain/kotlin/club/nito/feature/top/TopScreenUiState.kt rename feature/top/src/{androidMain => commonMain}/kotlin/club/nito/feature/top/component/ParticipantScheduleSection.kt (100%) create mode 100644 feature/top/src/commonMain/kotlin/club/nito/feature/top/di/topFeatureModule.kt create mode 100644 feature/top/src/iosMain/kotlin/club/nito/feature/top/.gitkeep delete mode 100644 feature/top/src/iosMain/kotlin/club/nito/feature/top/Platform.ios.kt diff --git a/app/android/src/main/java/club/nito/app/NitoApp.kt b/app/android/src/main/java/club/nito/app/NitoApp.kt index 4b5082a6..052f082a 100644 --- a/app/android/src/main/java/club/nito/app/NitoApp.kt +++ b/app/android/src/main/java/club/nito/app/NitoApp.kt @@ -6,6 +6,7 @@ import androidx.compose.material3.Surface import androidx.compose.material3.windowsizeclass.WindowSizeClass import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import club.nito.app.di.featureModules import club.nito.app.di.nitoDateTimeFormatterModule import club.nito.app.di.userMessageStateHolderModule import club.nito.core.data.di.dataModule @@ -14,6 +15,7 @@ import club.nito.core.domain.di.useCaseModule import club.nito.core.model.AuthStatus import club.nito.core.network.di.remoteDataSourceModule import club.nito.core.network.di.supabaseClientModule +import club.nito.feature.top.di.topFeatureModule import org.koin.compose.KoinApplication @Composable @@ -33,8 +35,11 @@ fun NitoApp( // fakeRemoteDataSourceModule, dataModule, useCaseModule, + topFeatureModule, ) + modules(featureModules) + // val kermit = Logger.withTag("koin") // logger(KermitKoinLogger(kermit)) }, diff --git a/app/android/src/main/java/club/nito/app/di/FeatureModules.kt b/app/android/src/main/java/club/nito/app/di/FeatureModules.kt new file mode 100644 index 00000000..d23afee0 --- /dev/null +++ b/app/android/src/main/java/club/nito/app/di/FeatureModules.kt @@ -0,0 +1,8 @@ +package club.nito.app.di + +import club.nito.feature.top.di.topFeatureModule +import org.koin.core.module.Module + +val featureModules: List = listOf( + topFeatureModule, +) diff --git a/core/ui/src/commonMain/kotlin/club/nito/core/ui/UiStateBuilder.kt b/core/ui/src/commonMain/kotlin/club/nito/core/ui/UiStateBuilder.kt new file mode 100644 index 00000000..05a152a3 --- /dev/null +++ b/core/ui/src/commonMain/kotlin/club/nito/core/ui/UiStateBuilder.kt @@ -0,0 +1,79 @@ +package club.nito.core.ui + +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.stateIn + +public fun StateMachine.buildUiState( + flow: StateFlow, + transform: (T1) -> R, +): StateFlow = flow.map(transform = transform) + .stateIn( + scope = stateMachineScope, + started = SharingStarted.WhileSubscribed(5_000), + initialValue = transform( + flow.value, + ), + ) + +public fun StateMachine.buildUiState( + flow: StateFlow, + flow2: StateFlow, + transform: (T1, T2) -> R, +): StateFlow = combine( + flow = flow, + flow2 = flow2, + transform = transform, +).stateIn( + scope = stateMachineScope, + started = SharingStarted.WhileSubscribed(5_000), + initialValue = transform( + flow.value, + flow2.value, + ), +) + +public fun StateMachine.buildUiState( + flow: StateFlow, + flow2: StateFlow, + flow3: StateFlow, + transform: (T1, T2, T3) -> R, +): StateFlow = combine( + flow = flow, + flow2 = flow2, + flow3 = flow3, + transform = transform, +).stateIn( + scope = stateMachineScope, + started = SharingStarted.WhileSubscribed(5_000), + initialValue = transform( + flow.value, + flow2.value, + flow3.value, + ), +) + +public fun StateMachine.buildUiState( + flow: StateFlow, + flow2: StateFlow, + flow3: StateFlow, + flow4: StateFlow, + transform: (T1, T2, T3, T4) -> R, +): StateFlow = combine( + flow = flow, + flow2 = flow2, + flow3 = flow3, + flow4 = flow4, + transform = transform, +).stateIn( + scope = stateMachineScope, + started = SharingStarted.WhileSubscribed(5_000), + initialValue = transform( + flow.value, + flow2.value, + flow3.value, + flow4.value, + ), +) diff --git a/feature/top/build.gradle.kts b/feature/top/build.gradle.kts index ffd904e1..42aeaefd 100644 --- a/feature/top/build.gradle.kts +++ b/feature/top/build.gradle.kts @@ -20,6 +20,9 @@ kotlin { implementation(projects.core.designsystem) implementation(libs.kotlinxCoroutinesCore) + + implementation(libs.koin) + implementation(libs.koinCompose) } } androidMain { diff --git a/feature/top/src/androidMain/kotlin/club/nito/feature/top/Platform.android.kt b/feature/top/src/androidMain/kotlin/club/nito/feature/top/Platform.android.kt deleted file mode 100644 index 17dc92a7..00000000 --- a/feature/top/src/androidMain/kotlin/club/nito/feature/top/Platform.android.kt +++ /dev/null @@ -1,7 +0,0 @@ -package club.nito.feature.top - -class AndroidPlatform : Platform { - override val name: String = "Android ${android.os.Build.VERSION.SDK_INT}" -} - -actual fun getPlatform(): Platform = AndroidPlatform() diff --git a/feature/top/src/androidMain/kotlin/club/nito/feature/top/TopEvent.kt b/feature/top/src/androidMain/kotlin/club/nito/feature/top/TopEvent.kt deleted file mode 100644 index c2a8a9e8..00000000 --- a/feature/top/src/androidMain/kotlin/club/nito/feature/top/TopEvent.kt +++ /dev/null @@ -1,6 +0,0 @@ -package club.nito.feature.top - -sealed class TopEvent { - data object NavigateToScheduleList : TopEvent() - data object NavigateToSettings : TopEvent() -} diff --git a/feature/top/src/androidMain/kotlin/club/nito/feature/top/TopIntent.kt b/feature/top/src/androidMain/kotlin/club/nito/feature/top/TopIntent.kt deleted file mode 100644 index 2f766aee..00000000 --- a/feature/top/src/androidMain/kotlin/club/nito/feature/top/TopIntent.kt +++ /dev/null @@ -1,11 +0,0 @@ -package club.nito.feature.top - -import club.nito.core.domain.model.ParticipantSchedule - -sealed class TopIntent { - data object ClickScheduleList : TopIntent() - data object ClickSettings : TopIntent() - data class ClickShowConfirmParticipateDialog(val schedule: ParticipantSchedule) : TopIntent() - data class ClickParticipateSchedule(val schedule: ParticipantSchedule) : TopIntent() - data object ClickDismissConfirmParticipateDialog : TopIntent() -} diff --git a/feature/top/src/androidMain/kotlin/club/nito/feature/top/TopScreenUiState.kt b/feature/top/src/androidMain/kotlin/club/nito/feature/top/TopScreenUiState.kt deleted file mode 100644 index 9d4c06b7..00000000 --- a/feature/top/src/androidMain/kotlin/club/nito/feature/top/TopScreenUiState.kt +++ /dev/null @@ -1,16 +0,0 @@ -package club.nito.feature.top - -import club.nito.core.common.NitoDateTimeFormatter -import club.nito.core.domain.model.ParticipantSchedule -import club.nito.core.model.FetchSingleContentResult - -data class TopScreenUiState( - val dateTimeFormatter: NitoDateTimeFormatter, - val recentSchedule: FetchSingleContentResult, - val confirmParticipateDialog: ConfirmParticipateDialogUiState, -) - -sealed class ConfirmParticipateDialogUiState { - data class Show(val schedule: ParticipantSchedule) : ConfirmParticipateDialogUiState() - data object Hide : ConfirmParticipateDialogUiState() -} diff --git a/feature/top/src/commonMain/kotlin/club/nito/feature/top/Greeting.kt b/feature/top/src/commonMain/kotlin/club/nito/feature/top/Greeting.kt deleted file mode 100644 index b410a847..00000000 --- a/feature/top/src/commonMain/kotlin/club/nito/feature/top/Greeting.kt +++ /dev/null @@ -1,9 +0,0 @@ -package club.nito.feature.top - -class Greeting { - private val platform: Platform = getPlatform() - - fun greet(): String { - return "Hello, ${platform.name}!" - } -} diff --git a/feature/top/src/commonMain/kotlin/club/nito/feature/top/Platform.kt b/feature/top/src/commonMain/kotlin/club/nito/feature/top/Platform.kt deleted file mode 100644 index 44854d5b..00000000 --- a/feature/top/src/commonMain/kotlin/club/nito/feature/top/Platform.kt +++ /dev/null @@ -1,7 +0,0 @@ -package club.nito.feature.top - -interface Platform { - val name: String -} - -expect fun getPlatform(): Platform diff --git a/feature/top/src/androidMain/kotlin/club/nito/feature/top/TopScreen.kt b/feature/top/src/commonMain/kotlin/club/nito/feature/top/TopScreen.kt similarity index 70% rename from feature/top/src/androidMain/kotlin/club/nito/feature/top/TopScreen.kt rename to feature/top/src/commonMain/kotlin/club/nito/feature/top/TopScreen.kt index 54a3197c..a675c148 100644 --- a/feature/top/src/androidMain/kotlin/club/nito/feature/top/TopScreen.kt +++ b/feature/top/src/commonMain/kotlin/club/nito/feature/top/TopScreen.kt @@ -5,11 +5,14 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Settings +import androidx.compose.material3.CenterAlignedTopAppBar import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton +import androidx.compose.material3.Scaffold import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState @@ -17,51 +20,48 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import androidx.hilt.navigation.compose.hiltViewModel -import club.nito.core.designsystem.component.CenterAlignedTopAppBar -import club.nito.core.designsystem.component.Scaffold -import club.nito.core.designsystem.component.Text import club.nito.core.ui.ConfirmParticipateDialog import club.nito.core.ui.message.SnackbarMessageEffect import club.nito.feature.top.component.ParticipantScheduleSection +import org.koin.compose.koinInject @Composable fun TopRoute( - viewModel: TopViewModel = hiltViewModel(), + stateMachine: TopStateMachine = koinInject(), onScheduleListClick: () -> Unit = {}, onSettingsClick: () -> Unit = {}, ) { - viewModel.event.collectAsState(initial = null).value?.let { + stateMachine.event.collectAsState(initial = null).value?.let { LaunchedEffect(it.hashCode()) { when (it) { - TopEvent.NavigateToScheduleList -> onScheduleListClick() - TopEvent.NavigateToSettings -> onSettingsClick() + TopScreenEvent.NavigateToScheduleList -> onScheduleListClick() + TopScreenEvent.NavigateToSettings -> onSettingsClick() } - viewModel.consume(it) + stateMachine.consume(it) } } - val uiState by viewModel.uiState.collectAsState() + val uiState by stateMachine.uiState.collectAsState() val snackbarHostState = remember { SnackbarHostState() } SnackbarMessageEffect( snackbarHostState = snackbarHostState, - userMessageStateHolder = viewModel.userMessageStateHolder, + userMessageStateHolder = stateMachine.userMessageStateHolder, ) TopScreen( uiState = uiState, snackbarHostState = snackbarHostState, - dispatch = viewModel::dispatch, + dispatch = stateMachine::dispatch, ) } @OptIn(ExperimentalMaterial3Api::class) @Composable -private fun TopScreen( +internal fun TopScreen( uiState: TopScreenUiState, snackbarHostState: SnackbarHostState, - dispatch: (TopIntent) -> Unit = {}, + dispatch: (TopScreenIntent) -> Unit = {}, ) { val recentSchedule = uiState.recentSchedule val confirmParticipateDialog = uiState.confirmParticipateDialog @@ -75,7 +75,7 @@ private fun TopScreen( ) }, actions = { - IconButton(onClick = { dispatch(TopIntent.ClickSettings) }) { + IconButton(onClick = { dispatch(TopScreenIntent.ClickSettings) }) { Icon( imageVector = Icons.Default.Settings, contentDescription = "Settings", @@ -90,8 +90,8 @@ private fun TopScreen( ConfirmParticipateDialog( schedule = confirmParticipateDialog.schedule, dateTimeFormatter = uiState.dateTimeFormatter, - onParticipateRequest = { dispatch(TopIntent.ClickParticipateSchedule(it)) }, - onDismissRequest = { dispatch(TopIntent.ClickDismissConfirmParticipateDialog) }, + onParticipateRequest = { dispatch(TopScreenIntent.ClickParticipateSchedule(it)) }, + onDismissRequest = { dispatch(TopScreenIntent.ClickDismissConfirmParticipateDialog) }, ) } @@ -104,8 +104,8 @@ private fun TopScreen( ParticipantScheduleSection( recentSchedule = recentSchedule, dateTimeFormatter = uiState.dateTimeFormatter, - onRecentScheduleClick = { dispatch(TopIntent.ClickShowConfirmParticipateDialog(it)) }, - onScheduleListClick = { dispatch(TopIntent.ClickScheduleList) }, + onRecentScheduleClick = { dispatch(TopScreenIntent.ClickShowConfirmParticipateDialog(it)) }, + onScheduleListClick = { dispatch(TopScreenIntent.ClickScheduleList) }, ) } }, diff --git a/feature/top/src/commonMain/kotlin/club/nito/feature/top/TopScreenEvent.kt b/feature/top/src/commonMain/kotlin/club/nito/feature/top/TopScreenEvent.kt new file mode 100644 index 00000000..22a16ecd --- /dev/null +++ b/feature/top/src/commonMain/kotlin/club/nito/feature/top/TopScreenEvent.kt @@ -0,0 +1,13 @@ +package club.nito.feature.top + +sealed class TopScreenEvent { + /** + * Navigate to schedule list screen + */ + data object NavigateToScheduleList : TopScreenEvent() + + /** + * Navigate to settings screen + */ + data object NavigateToSettings : TopScreenEvent() +} diff --git a/feature/top/src/commonMain/kotlin/club/nito/feature/top/TopScreenIntent.kt b/feature/top/src/commonMain/kotlin/club/nito/feature/top/TopScreenIntent.kt new file mode 100644 index 00000000..10660d7d --- /dev/null +++ b/feature/top/src/commonMain/kotlin/club/nito/feature/top/TopScreenIntent.kt @@ -0,0 +1,30 @@ +package club.nito.feature.top + +import club.nito.core.domain.model.ParticipantSchedule + +sealed class TopScreenIntent { + /** + * Click schedule list + */ + data object ClickScheduleList : TopScreenIntent() + + /** + * Click settings + */ + data object ClickSettings : TopScreenIntent() + + /** + * Click show confirm participate dialog + */ + data class ClickShowConfirmParticipateDialog(val schedule: ParticipantSchedule) : TopScreenIntent() + + /** + * Click participate schedule + */ + data class ClickParticipateSchedule(val schedule: ParticipantSchedule) : TopScreenIntent() + + /** + * Click dismiss confirm participate dialog + */ + data object ClickDismissConfirmParticipateDialog : TopScreenIntent() +} diff --git a/feature/top/src/androidMain/kotlin/club/nito/feature/top/TopViewModel.kt b/feature/top/src/commonMain/kotlin/club/nito/feature/top/TopScreenState.kt similarity index 61% rename from feature/top/src/androidMain/kotlin/club/nito/feature/top/TopViewModel.kt rename to feature/top/src/commonMain/kotlin/club/nito/feature/top/TopScreenState.kt index 82018ecb..d85389f5 100644 --- a/feature/top/src/androidMain/kotlin/club/nito/feature/top/TopViewModel.kt +++ b/feature/top/src/commonMain/kotlin/club/nito/feature/top/TopScreenState.kt @@ -1,14 +1,12 @@ package club.nito.feature.top -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope import club.nito.core.common.NitoDateTimeFormatter import club.nito.core.domain.GetRecentScheduleUseCase import club.nito.core.domain.model.ParticipantSchedule import club.nito.core.model.FetchSingleContentResult +import club.nito.core.ui.StateMachine import club.nito.core.ui.buildUiState import club.nito.core.ui.message.UserMessageStateHolder -import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted @@ -16,19 +14,16 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch -import javax.inject.Inject -@HiltViewModel -class TopViewModel @Inject constructor( - getRecentScheduleUseCase: GetRecentScheduleUseCase, +class TopStateMachine internal constructor( + getRecentSchedule: GetRecentScheduleUseCase, val userMessageStateHolder: UserMessageStateHolder, private val dateTimeFormatter: NitoDateTimeFormatter, -) : ViewModel(), - UserMessageStateHolder by userMessageStateHolder { +) : StateMachine(), UserMessageStateHolder by userMessageStateHolder { private val showConfirmParticipateSchedule = MutableStateFlow(null) - private val recentSchedule = getRecentScheduleUseCase().stateIn( - scope = viewModelScope, + private val recentSchedule = getRecentSchedule().stateIn( + scope = stateMachineScope, started = SharingStarted.WhileSubscribed(5_000), initialValue = FetchSingleContentResult.Loading, ) @@ -46,29 +41,29 @@ class TopViewModel @Inject constructor( ) } - private val _events = MutableStateFlow>(emptyList()) - val event: Flow = _events.map { it.firstOrNull() } + private val _events = MutableStateFlow>(emptyList()) + val event: Flow = _events.map { it.firstOrNull() } - fun dispatch(intent: TopIntent) { - viewModelScope.launch { + fun dispatch(intent: TopScreenIntent) { + stateMachineScope.launch { when (intent) { - is TopIntent.ClickShowConfirmParticipateDialog -> showConfirmParticipateSchedule.emit(intent.schedule) - is TopIntent.ClickParticipateSchedule -> { + is TopScreenIntent.ClickShowConfirmParticipateDialog -> showConfirmParticipateSchedule.emit(intent.schedule) + is TopScreenIntent.ClickParticipateSchedule -> { showConfirmParticipateSchedule.emit(null) val scheduledAt = dateTimeFormatter.formatDateTimeString(intent.schedule.scheduledAt) userMessageStateHolder.showMessage("$scheduledAt に参加登録しました 🎉") } - TopIntent.ClickDismissConfirmParticipateDialog -> showConfirmParticipateSchedule.emit(null) - TopIntent.ClickScheduleList -> _events.emit(_events.value + TopEvent.NavigateToScheduleList) - TopIntent.ClickSettings -> _events.emit(_events.value + TopEvent.NavigateToSettings) + TopScreenIntent.ClickDismissConfirmParticipateDialog -> showConfirmParticipateSchedule.emit(null) + TopScreenIntent.ClickScheduleList -> _events.emit(_events.value + TopScreenEvent.NavigateToScheduleList) + TopScreenIntent.ClickSettings -> _events.emit(_events.value + TopScreenEvent.NavigateToSettings) } } } - fun consume(event: TopEvent) { - viewModelScope.launch { + fun consume(event: TopScreenEvent) { + stateMachineScope.launch { _events.emit(_events.value.filterNot { it == event }) } } diff --git a/feature/top/src/commonMain/kotlin/club/nito/feature/top/TopScreenUiState.kt b/feature/top/src/commonMain/kotlin/club/nito/feature/top/TopScreenUiState.kt new file mode 100644 index 00000000..f6b287c9 --- /dev/null +++ b/feature/top/src/commonMain/kotlin/club/nito/feature/top/TopScreenUiState.kt @@ -0,0 +1,33 @@ +package club.nito.feature.top + +import club.nito.core.common.NitoDateTimeFormatter +import club.nito.core.domain.model.ParticipantSchedule +import club.nito.core.model.FetchSingleContentResult + +/** + * Top screen ui state + * @param dateTimeFormatter Date time formatter + * @param recentSchedule Recent schedule + * @param confirmParticipateDialog Confirm participate dialog + */ +data class TopScreenUiState internal constructor( + val dateTimeFormatter: NitoDateTimeFormatter, + val recentSchedule: FetchSingleContentResult, + val confirmParticipateDialog: ConfirmParticipateDialogUiState, +) + +/** + * Confirm participate dialog ui state + */ +sealed class ConfirmParticipateDialogUiState { + /** + * Show confirm participate dialog + * @param schedule Schedule + */ + data class Show internal constructor(val schedule: ParticipantSchedule) : ConfirmParticipateDialogUiState() + + /** + * Hide confirm participate dialog + */ + data object Hide : ConfirmParticipateDialogUiState() +} diff --git a/feature/top/src/androidMain/kotlin/club/nito/feature/top/component/ParticipantScheduleSection.kt b/feature/top/src/commonMain/kotlin/club/nito/feature/top/component/ParticipantScheduleSection.kt similarity index 100% rename from feature/top/src/androidMain/kotlin/club/nito/feature/top/component/ParticipantScheduleSection.kt rename to feature/top/src/commonMain/kotlin/club/nito/feature/top/component/ParticipantScheduleSection.kt diff --git a/feature/top/src/commonMain/kotlin/club/nito/feature/top/di/topFeatureModule.kt b/feature/top/src/commonMain/kotlin/club/nito/feature/top/di/topFeatureModule.kt new file mode 100644 index 00000000..11be0372 --- /dev/null +++ b/feature/top/src/commonMain/kotlin/club/nito/feature/top/di/topFeatureModule.kt @@ -0,0 +1,15 @@ +package club.nito.feature.top.di + +import club.nito.feature.top.TopStateMachine +import org.koin.core.module.Module +import org.koin.dsl.module + +val topFeatureModule: Module = module { + factory { + TopStateMachine( + getRecentSchedule = get(), + userMessageStateHolder = get(), + dateTimeFormatter = get(), + ) + } +} diff --git a/feature/top/src/iosMain/kotlin/club/nito/feature/top/.gitkeep b/feature/top/src/iosMain/kotlin/club/nito/feature/top/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/feature/top/src/iosMain/kotlin/club/nito/feature/top/Platform.ios.kt b/feature/top/src/iosMain/kotlin/club/nito/feature/top/Platform.ios.kt deleted file mode 100644 index d31c7186..00000000 --- a/feature/top/src/iosMain/kotlin/club/nito/feature/top/Platform.ios.kt +++ /dev/null @@ -1,9 +0,0 @@ -package club.nito.feature.top - -import platform.UIKit.UIDevice - -class IOSPlatform : Platform { - override val name: String = UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion -} - -actual fun getPlatform(): Platform = IOSPlatform()