From 40ab25798c49a778e0c75b11ba74e6592f7840f0 Mon Sep 17 00:00:00 2001 From: todayama_r <13657682+Corvus400@users.noreply.github.com> Date: Sun, 25 Sep 2022 07:08:40 +0900 Subject: [PATCH 01/12] :recycle: Update Introduce error handring to contributors --- .../DataContributorsRepository.kt | 19 ++++---- .../FakeContributorsRepository.kt | 1 - .../feature/contributors/Contributors.kt | 25 ++++++++++- .../contributors/ContributorsUiModel.kt | 6 ++- .../contributors/ContributorsViewModel.kt | 43 ++++++++++++++++--- 5 files changed, 76 insertions(+), 18 deletions(-) diff --git a/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/contributors/DataContributorsRepository.kt b/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/contributors/DataContributorsRepository.kt index 87d77f3d..de88be1e 100644 --- a/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/contributors/DataContributorsRepository.kt +++ b/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/contributors/DataContributorsRepository.kt @@ -3,27 +3,30 @@ package io.github.droidkaigi.confsched2022.data.contributors import io.github.droidkaigi.confsched2022.model.Contributor import io.github.droidkaigi.confsched2022.model.ContributorsRepository import kotlinx.collections.immutable.PersistentList +import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toPersistentList -import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.callbackFlow // TODO: Move to core-testing, once contributors server is created public class DataContributorsRepository( private val contributorsApi: ContributorsApi, ) : ContributorsRepository { + private val contributorsStateFlow = + MutableStateFlow>(persistentListOf()) + override fun contributors(): Flow> { return callbackFlow { - send( - contributorsApi - .contributors() - .toPersistentList() - ) - awaitClose { } + contributorsStateFlow.collect { + send(it) + } } } override suspend fun refresh() { - TODO("Not yet implemented") + contributorsStateFlow.value = contributorsApi + .contributors() + .toPersistentList() } } diff --git a/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/contributors/FakeContributorsRepository.kt b/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/contributors/FakeContributorsRepository.kt index 4b6b3357..9824f123 100644 --- a/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/contributors/FakeContributorsRepository.kt +++ b/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/contributors/FakeContributorsRepository.kt @@ -14,6 +14,5 @@ public class FakeContributorsRepository : ContributorsRepository { } override suspend fun refresh() { - TODO("Not yet implemented") } } diff --git a/feature/contributors/src/main/java/io/github/droidkaigi/confsched2022/feature/contributors/Contributors.kt b/feature/contributors/src/main/java/io/github/droidkaigi/confsched2022/feature/contributors/Contributors.kt index 082af67d..fc2d3427 100644 --- a/feature/contributors/src/main/java/io/github/droidkaigi/confsched2022/feature/contributors/Contributors.kt +++ b/feature/contributors/src/main/java/io/github/droidkaigi/confsched2022/feature/contributors/Contributors.kt @@ -7,9 +7,11 @@ 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.SnackbarHostState import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview @@ -19,6 +21,7 @@ import io.github.droidkaigi.confsched2022.designsystem.components.KaigiScaffold import io.github.droidkaigi.confsched2022.designsystem.components.KaigiTopAppBar import io.github.droidkaigi.confsched2022.designsystem.components.UsernameRow import io.github.droidkaigi.confsched2022.designsystem.theme.KaigiTheme +import io.github.droidkaigi.confsched2022.feature.announcement.AppErrorSnackbarEffect import io.github.droidkaigi.confsched2022.model.Contributor import io.github.droidkaigi.confsched2022.model.fakes import io.github.droidkaigi.confsched2022.strings.Strings @@ -38,6 +41,8 @@ fun ContributorsScreenRoot( uiModel = uiModel, showNavigationIcon = showNavigationIcon, onNavigationIconClick = onNavigationIconClick, + onRetryButtonClick = { viewModel.onRetryButtonClick() }, + onAppErrorNotified = { viewModel.onAppErrorNotified() }, onLinkClick = onLinkClick ) } @@ -47,10 +52,15 @@ fun Contributors( uiModel: ContributorsUiModel, showNavigationIcon: Boolean, onNavigationIconClick: () -> Unit, + onRetryButtonClick: () -> Unit, + onAppErrorNotified: () -> Unit, onLinkClick: (url: String, packageName: String?) -> Unit, modifier: Modifier = Modifier, ) { + val snackbarHostState = remember { SnackbarHostState() } + KaigiScaffold( + snackbarHostState = snackbarHostState, modifier = modifier, topBar = { KaigiTopAppBar( @@ -64,9 +74,17 @@ fun Contributors( ) } ) { innerPadding -> + AppErrorSnackbarEffect( + appError = uiModel.appError, + snackBarHostState = snackbarHostState, + onAppErrorNotified = onAppErrorNotified, + onRetryButtonClick = onRetryButtonClick + ) Box { when (uiModel.state) { - is Error -> TODO() + is Error -> { + // Do nothing + } Loading -> Box( modifier = Modifier.padding(innerPadding).fillMaxSize(), contentAlignment = Alignment.Center, @@ -103,10 +121,13 @@ fun ContributorsPreview() { uiModel = ContributorsUiModel( state = Success( Contributor.fakes() - ) + ), + appError = null, ), showNavigationIcon = true, onNavigationIconClick = {}, + onRetryButtonClick = {}, + onAppErrorNotified = {}, onLinkClick = { _, _ -> }, ) } diff --git a/feature/contributors/src/main/java/io/github/droidkaigi/confsched2022/feature/contributors/ContributorsUiModel.kt b/feature/contributors/src/main/java/io/github/droidkaigi/confsched2022/feature/contributors/ContributorsUiModel.kt index a07ddd2d..6d167e09 100644 --- a/feature/contributors/src/main/java/io/github/droidkaigi/confsched2022/feature/contributors/ContributorsUiModel.kt +++ b/feature/contributors/src/main/java/io/github/droidkaigi/confsched2022/feature/contributors/ContributorsUiModel.kt @@ -1,7 +1,11 @@ package io.github.droidkaigi.confsched2022.feature.contributors +import io.github.droidkaigi.confsched2022.model.AppError import io.github.droidkaigi.confsched2022.model.Contributor import io.github.droidkaigi.confsched2022.ui.UiLoadState import kotlinx.collections.immutable.PersistentList -data class ContributorsUiModel(val state: UiLoadState>) +data class ContributorsUiModel( + val state: UiLoadState>, + val appError: AppError? +) diff --git a/feature/contributors/src/main/java/io/github/droidkaigi/confsched2022/feature/contributors/ContributorsViewModel.kt b/feature/contributors/src/main/java/io/github/droidkaigi/confsched2022/feature/contributors/ContributorsViewModel.kt index 86aab043..0460b504 100644 --- a/feature/contributors/src/main/java/io/github/droidkaigi/confsched2022/feature/contributors/ContributorsViewModel.kt +++ b/feature/contributors/src/main/java/io/github/droidkaigi/confsched2022/feature/contributors/ContributorsViewModel.kt @@ -3,33 +3,64 @@ package io.github.droidkaigi.confsched2022.feature.contributors import androidx.compose.runtime.State import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import app.cash.molecule.AndroidUiDispatcher import app.cash.molecule.RecompositionClock.ContextClock import dagger.hilt.android.lifecycle.HiltViewModel +import io.github.droidkaigi.confsched2022.model.AppError import io.github.droidkaigi.confsched2022.model.ContributorsRepository import io.github.droidkaigi.confsched2022.ui.UiLoadState import io.github.droidkaigi.confsched2022.ui.asLoadState import io.github.droidkaigi.confsched2022.ui.moleculeComposeState import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel class ContributorsViewModel @Inject constructor( - contributorsRepository: ContributorsRepository, + private val contributorsRepository: ContributorsRepository, ) : ViewModel() { private val moleculeScope = CoroutineScope(viewModelScope.coroutineContext + AndroidUiDispatcher.Main) - val uiModel: State + private val contributorsFlow = contributorsRepository + .contributors() + .asLoadState() + + private var appError by mutableStateOf(null) + + val uiModel: State = moleculeScope.moleculeComposeState( + clock = ContextClock + ) { + val contributorLoadState by contributorsFlow.collectAsState(initial = UiLoadState.Loading) + ContributorsUiModel( + state = contributorLoadState, + appError = appError + ) + } init { - val dataFlow = contributorsRepository.contributors().asLoadState() + refresh() + } - uiModel = moleculeScope.moleculeComposeState(clock = ContextClock) { - val data by dataFlow.collectAsState(initial = UiLoadState.Loading) - ContributorsUiModel(data) + fun onRetryButtonClick() { + refresh() + } + + private fun refresh() { + viewModelScope.launch { + try { + contributorsRepository.refresh() + } catch (e: AppError) { + appError = e + } } } + + fun onAppErrorNotified() { + appError = null + } } From 4fe77ca61da80c681f4f1340c7d9da9ef38da5d3 Mon Sep 17 00:00:00 2001 From: todayama_r <13657682+Corvus400@users.noreply.github.com> Date: Sun, 25 Sep 2022 07:10:31 +0900 Subject: [PATCH 02/12] :memo: Change Moved the AppErrorSnackbarEffect class package to common. --- .../feature/{announcement => common}/AppErrorSnackbarEffect.kt | 2 +- .../confsched2022/feature/announcement/Announcements.kt | 1 + .../confsched2022/feature/contributors/Contributors.kt | 2 +- .../droidkaigi/confsched2022/feature/sessions/Sessions.kt | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) rename core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/{announcement => common}/AppErrorSnackbarEffect.kt (94%) diff --git a/core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/AppErrorSnackbarEffect.kt b/core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/common/AppErrorSnackbarEffect.kt similarity index 94% rename from core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/AppErrorSnackbarEffect.kt rename to core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/common/AppErrorSnackbarEffect.kt index 3d097df6..541924d6 100644 --- a/core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/AppErrorSnackbarEffect.kt +++ b/core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/common/AppErrorSnackbarEffect.kt @@ -1,4 +1,4 @@ -package io.github.droidkaigi.confsched2022.feature.announcement +package io.github.droidkaigi.confsched2022.feature.common import androidx.compose.material3.SnackbarDuration.Long import androidx.compose.material3.SnackbarHostState diff --git a/feature/announcement/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/Announcements.kt b/feature/announcement/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/Announcements.kt index 82547aa8..4a895143 100644 --- a/feature/announcement/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/Announcements.kt +++ b/feature/announcement/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/Announcements.kt @@ -37,6 +37,7 @@ import io.github.droidkaigi.confsched2022.designsystem.components.KaigiScaffold import io.github.droidkaigi.confsched2022.designsystem.components.KaigiTopAppBar import io.github.droidkaigi.confsched2022.designsystem.theme.KaigiColors import io.github.droidkaigi.confsched2022.designsystem.theme.KaigiTheme +import io.github.droidkaigi.confsched2022.feature.common.AppErrorSnackbarEffect import io.github.droidkaigi.confsched2022.model.AnnouncementsByDate import io.github.droidkaigi.confsched2022.model.fakes import io.github.droidkaigi.confsched2022.strings.Strings diff --git a/feature/contributors/src/main/java/io/github/droidkaigi/confsched2022/feature/contributors/Contributors.kt b/feature/contributors/src/main/java/io/github/droidkaigi/confsched2022/feature/contributors/Contributors.kt index fc2d3427..a1517c0c 100644 --- a/feature/contributors/src/main/java/io/github/droidkaigi/confsched2022/feature/contributors/Contributors.kt +++ b/feature/contributors/src/main/java/io/github/droidkaigi/confsched2022/feature/contributors/Contributors.kt @@ -21,7 +21,7 @@ import io.github.droidkaigi.confsched2022.designsystem.components.KaigiScaffold import io.github.droidkaigi.confsched2022.designsystem.components.KaigiTopAppBar import io.github.droidkaigi.confsched2022.designsystem.components.UsernameRow import io.github.droidkaigi.confsched2022.designsystem.theme.KaigiTheme -import io.github.droidkaigi.confsched2022.feature.announcement.AppErrorSnackbarEffect +import io.github.droidkaigi.confsched2022.feature.common.AppErrorSnackbarEffect import io.github.droidkaigi.confsched2022.model.Contributor import io.github.droidkaigi.confsched2022.model.fakes import io.github.droidkaigi.confsched2022.strings.Strings diff --git a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/Sessions.kt b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/Sessions.kt index eca80447..319d388e 100644 --- a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/Sessions.kt +++ b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/Sessions.kt @@ -66,7 +66,7 @@ import dev.icerock.moko.resources.compose.stringResource import io.github.droidkaigi.confsched2022.designsystem.components.KaigiScaffold import io.github.droidkaigi.confsched2022.designsystem.components.KaigiTopAppBar import io.github.droidkaigi.confsched2022.designsystem.theme.KaigiTheme -import io.github.droidkaigi.confsched2022.feature.announcement.AppErrorSnackbarEffect +import io.github.droidkaigi.confsched2022.feature.common.AppErrorSnackbarEffect import io.github.droidkaigi.confsched2022.model.DroidKaigi2022Day import io.github.droidkaigi.confsched2022.model.DroidKaigiSchedule import io.github.droidkaigi.confsched2022.model.TimetableItemId From 64355fb923e18d049b44402aeec6aea679bf6d9d Mon Sep 17 00:00:00 2001 From: todayama_r <13657682+Corvus400@users.noreply.github.com> Date: Sun, 25 Sep 2022 07:52:52 +0900 Subject: [PATCH 03/12] :recycle: Update Introduce error handring to sponsors --- .../data/sponsors/DataSponsorsRepository.kt | 17 +++++-- .../data/sponsors/FakeSponsorsRepository.kt | 3 ++ .../confsched2022/model/SponsorsRepository.kt | 2 + .../feature/sponsors/Sponsors.kt | 22 +++++++- .../feature/sponsors/SponsorsUiModel.kt | 4 +- .../feature/sponsors/SponsorsViewModel.kt | 50 +++++++++++++++---- 6 files changed, 80 insertions(+), 18 deletions(-) diff --git a/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/sponsors/DataSponsorsRepository.kt b/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/sponsors/DataSponsorsRepository.kt index f0acea5a..a95e36be 100644 --- a/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/sponsors/DataSponsorsRepository.kt +++ b/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/sponsors/DataSponsorsRepository.kt @@ -3,18 +3,25 @@ package io.github.droidkaigi.confsched2022.data.sponsors import io.github.droidkaigi.confsched2022.model.Sponsor import io.github.droidkaigi.confsched2022.model.SponsorsRepository import kotlinx.collections.immutable.PersistentList -import kotlinx.coroutines.channels.awaitClose +import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.callbackFlow public class DataSponsorsRepository( private val sponsorsApi: SponsorsApi ) : SponsorsRepository { + private val sponsorsStateFlow = + MutableStateFlow>(persistentListOf()) override fun sponsors(): Flow> = callbackFlow { - send( - sponsorsApi.sponsors() - ) - awaitClose { } + sponsorsStateFlow.collect { + send(it) + } } + + override suspend fun refresh() { + sponsorsStateFlow.value = sponsorsApi + .sponsors() + } } diff --git a/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/sponsors/FakeSponsorsRepository.kt b/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/sponsors/FakeSponsorsRepository.kt index 6ef626c9..02655f1d 100644 --- a/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/sponsors/FakeSponsorsRepository.kt +++ b/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/sponsors/FakeSponsorsRepository.kt @@ -9,4 +9,7 @@ import kotlinx.coroutines.flow.flowOf public class FakeSponsorsRepository : SponsorsRepository { override fun sponsors(): Flow> = flowOf(Sponsor.fakes()) + + override suspend fun refresh() { + } } diff --git a/core/model/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/model/SponsorsRepository.kt b/core/model/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/model/SponsorsRepository.kt index 1fc95c35..238451e3 100644 --- a/core/model/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/model/SponsorsRepository.kt +++ b/core/model/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/model/SponsorsRepository.kt @@ -5,4 +5,6 @@ import kotlinx.coroutines.flow.Flow public interface SponsorsRepository { public fun sponsors(): Flow> + + public suspend fun refresh() } diff --git a/feature/sponsors/src/main/java/io/github/droidkaigi/confsched2022/feature/sponsors/Sponsors.kt b/feature/sponsors/src/main/java/io/github/droidkaigi/confsched2022/feature/sponsors/Sponsors.kt index eab9103e..dad6f512 100644 --- a/feature/sponsors/src/main/java/io/github/droidkaigi/confsched2022/feature/sponsors/Sponsors.kt +++ b/feature/sponsors/src/main/java/io/github/droidkaigi/confsched2022/feature/sponsors/Sponsors.kt @@ -20,9 +20,11 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.Divider import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -32,6 +34,7 @@ import coil.compose.AsyncImage import dev.icerock.moko.resources.compose.stringResource import io.github.droidkaigi.confsched2022.designsystem.components.KaigiScaffold import io.github.droidkaigi.confsched2022.designsystem.components.KaigiTopAppBar +import io.github.droidkaigi.confsched2022.feature.announcement.AppErrorSnackbarEffect import io.github.droidkaigi.confsched2022.feature.sponsors.SponsorPlan.Gold import io.github.droidkaigi.confsched2022.feature.sponsors.SponsorPlan.Platinum import io.github.droidkaigi.confsched2022.feature.sponsors.SponsorPlan.Supporter @@ -55,6 +58,8 @@ fun SponsorsScreenRoot( uiModel = uiModel, showNavigationIcon = showNavigationIcon, onNavigationIconClick = onNavigationIconClick, + onRetryButtonClick = { viewModel.onRetryButtonClick() }, + onAppErrorNotified = { viewModel.onAppErrorNotified() }, onItemClick = onItemClick ) } @@ -64,10 +69,15 @@ fun Sponsors( uiModel: SponsorsUiModel, showNavigationIcon: Boolean, onNavigationIconClick: () -> Unit, + onRetryButtonClick: () -> Unit, + onAppErrorNotified: () -> Unit, modifier: Modifier = Modifier, onItemClick: (url: String) -> Unit = { _ -> }, ) { + val snackbarHostState = remember { SnackbarHostState() } + KaigiScaffold( + snackbarHostState = snackbarHostState, modifier = modifier, topBar = { KaigiTopAppBar( @@ -81,6 +91,12 @@ fun Sponsors( ) } ) { innerPadding -> + AppErrorSnackbarEffect( + appError = uiModel.appError, + snackBarHostState = snackbarHostState, + onAppErrorNotified = onAppErrorNotified, + onRetryButtonClick = onRetryButtonClick + ) when (uiModel.state) { Loading -> FullScreenLoading(Modifier.padding(innerPadding)) is Success -> @@ -98,7 +114,9 @@ fun Sponsors( onItemClick = onItemClick ) } - is Error -> TODO() + is Error -> { + // Do nothing + } } } } @@ -206,4 +224,4 @@ private fun SponsorDivider() { modifier = Modifier.padding(vertical = 8.dp, horizontal = 16.dp), color = MaterialTheme.colorScheme.outline ) -} +} \ No newline at end of file diff --git a/feature/sponsors/src/main/java/io/github/droidkaigi/confsched2022/feature/sponsors/SponsorsUiModel.kt b/feature/sponsors/src/main/java/io/github/droidkaigi/confsched2022/feature/sponsors/SponsorsUiModel.kt index bc31140d..063e517e 100644 --- a/feature/sponsors/src/main/java/io/github/droidkaigi/confsched2022/feature/sponsors/SponsorsUiModel.kt +++ b/feature/sponsors/src/main/java/io/github/droidkaigi/confsched2022/feature/sponsors/SponsorsUiModel.kt @@ -1,8 +1,10 @@ package io.github.droidkaigi.confsched2022.feature.sponsors +import io.github.droidkaigi.confsched2022.model.AppError import io.github.droidkaigi.confsched2022.ui.UiLoadState import kotlinx.collections.immutable.PersistentList data class SponsorsUiModel( - val state: UiLoadState> + val state: UiLoadState>, + val appError: AppError? ) diff --git a/feature/sponsors/src/main/java/io/github/droidkaigi/confsched2022/feature/sponsors/SponsorsViewModel.kt b/feature/sponsors/src/main/java/io/github/droidkaigi/confsched2022/feature/sponsors/SponsorsViewModel.kt index 7ec6b4cb..c3f81c12 100644 --- a/feature/sponsors/src/main/java/io/github/droidkaigi/confsched2022/feature/sponsors/SponsorsViewModel.kt +++ b/feature/sponsors/src/main/java/io/github/droidkaigi/confsched2022/feature/sponsors/SponsorsViewModel.kt @@ -3,6 +3,8 @@ package io.github.droidkaigi.confsched2022.feature.sponsors import androidx.compose.runtime.State import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import app.cash.molecule.AndroidUiDispatcher @@ -13,6 +15,7 @@ import io.github.droidkaigi.confsched2022.feature.sponsors.SponsorItem.Title import io.github.droidkaigi.confsched2022.feature.sponsors.SponsorPlan.Gold import io.github.droidkaigi.confsched2022.feature.sponsors.SponsorPlan.Platinum import io.github.droidkaigi.confsched2022.feature.sponsors.SponsorPlan.Supporter +import io.github.droidkaigi.confsched2022.model.AppError import io.github.droidkaigi.confsched2022.model.Plan import io.github.droidkaigi.confsched2022.model.Plan.GOLD import io.github.droidkaigi.confsched2022.model.Plan.PLATINUM @@ -26,26 +29,35 @@ import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.toPersistentList import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.map +import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel class SponsorsViewModel @Inject constructor( - sponsorsRepository: SponsorsRepository + private val sponsorsRepository: SponsorsRepository ) : ViewModel() { private val moleculeScope = CoroutineScope(viewModelScope.coroutineContext + AndroidUiDispatcher.Main) - val uiModel: State + private val sponsorsFlow = sponsorsRepository + .sponsors() + .map { it.mapToSponsorItems() } + .asLoadState() - init { - val sponsorsFlow = sponsorsRepository.sponsors() - .map { it.mapToSponsorItems() } - .asLoadState() + private var appError by mutableStateOf(null) - uiModel = moleculeScope.moleculeComposeState(clock = ContextClock) { - val sponsors by sponsorsFlow.collectAsState(initial = UiLoadState.Loading) - SponsorsUiModel(sponsors) - } + val uiModel: State = moleculeScope.moleculeComposeState( + clock = ContextClock + ) { + val sponsorLoadState by sponsorsFlow.collectAsState(initial = UiLoadState.Loading) + SponsorsUiModel( + state = sponsorLoadState, + appError = appError + ) + } + + init { + refresh() } private fun PersistentList.mapToSponsorItems(): PersistentList { @@ -87,4 +99,22 @@ class SponsorsViewModel @Inject constructor( link = link ) } + + fun onRetryButtonClick() { + refresh() + } + + private fun refresh() { + viewModelScope.launch { + try { + sponsorsRepository.refresh() + } catch (e: AppError) { + appError = e + } + } + } + + fun onAppErrorNotified() { + appError = null + } } From 8df3d2f8d78c8446c1143096657764b9c5162c67 Mon Sep 17 00:00:00 2001 From: todayama_r <13657682+Corvus400@users.noreply.github.com> Date: Sun, 25 Sep 2022 07:57:56 +0900 Subject: [PATCH 04/12] :memo: Change Moved the AppErrorSnackbarEffect class package to common. --- .../feature/{announcement => common}/AppErrorSnackbarEffect.kt | 2 +- .../confsched2022/feature/announcement/Announcements.kt | 1 + .../droidkaigi/confsched2022/feature/sessions/Sessions.kt | 2 +- .../droidkaigi/confsched2022/feature/sponsors/Sponsors.kt | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) rename core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/{announcement => common}/AppErrorSnackbarEffect.kt (94%) diff --git a/core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/AppErrorSnackbarEffect.kt b/core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/common/AppErrorSnackbarEffect.kt similarity index 94% rename from core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/AppErrorSnackbarEffect.kt rename to core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/common/AppErrorSnackbarEffect.kt index 3d097df6..541924d6 100644 --- a/core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/AppErrorSnackbarEffect.kt +++ b/core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/common/AppErrorSnackbarEffect.kt @@ -1,4 +1,4 @@ -package io.github.droidkaigi.confsched2022.feature.announcement +package io.github.droidkaigi.confsched2022.feature.common import androidx.compose.material3.SnackbarDuration.Long import androidx.compose.material3.SnackbarHostState diff --git a/feature/announcement/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/Announcements.kt b/feature/announcement/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/Announcements.kt index 82547aa8..4a895143 100644 --- a/feature/announcement/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/Announcements.kt +++ b/feature/announcement/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/Announcements.kt @@ -37,6 +37,7 @@ import io.github.droidkaigi.confsched2022.designsystem.components.KaigiScaffold import io.github.droidkaigi.confsched2022.designsystem.components.KaigiTopAppBar import io.github.droidkaigi.confsched2022.designsystem.theme.KaigiColors import io.github.droidkaigi.confsched2022.designsystem.theme.KaigiTheme +import io.github.droidkaigi.confsched2022.feature.common.AppErrorSnackbarEffect import io.github.droidkaigi.confsched2022.model.AnnouncementsByDate import io.github.droidkaigi.confsched2022.model.fakes import io.github.droidkaigi.confsched2022.strings.Strings diff --git a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/Sessions.kt b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/Sessions.kt index eca80447..319d388e 100644 --- a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/Sessions.kt +++ b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/Sessions.kt @@ -66,7 +66,7 @@ import dev.icerock.moko.resources.compose.stringResource import io.github.droidkaigi.confsched2022.designsystem.components.KaigiScaffold import io.github.droidkaigi.confsched2022.designsystem.components.KaigiTopAppBar import io.github.droidkaigi.confsched2022.designsystem.theme.KaigiTheme -import io.github.droidkaigi.confsched2022.feature.announcement.AppErrorSnackbarEffect +import io.github.droidkaigi.confsched2022.feature.common.AppErrorSnackbarEffect import io.github.droidkaigi.confsched2022.model.DroidKaigi2022Day import io.github.droidkaigi.confsched2022.model.DroidKaigiSchedule import io.github.droidkaigi.confsched2022.model.TimetableItemId diff --git a/feature/sponsors/src/main/java/io/github/droidkaigi/confsched2022/feature/sponsors/Sponsors.kt b/feature/sponsors/src/main/java/io/github/droidkaigi/confsched2022/feature/sponsors/Sponsors.kt index dad6f512..0f0c4afd 100644 --- a/feature/sponsors/src/main/java/io/github/droidkaigi/confsched2022/feature/sponsors/Sponsors.kt +++ b/feature/sponsors/src/main/java/io/github/droidkaigi/confsched2022/feature/sponsors/Sponsors.kt @@ -34,7 +34,7 @@ import coil.compose.AsyncImage import dev.icerock.moko.resources.compose.stringResource import io.github.droidkaigi.confsched2022.designsystem.components.KaigiScaffold import io.github.droidkaigi.confsched2022.designsystem.components.KaigiTopAppBar -import io.github.droidkaigi.confsched2022.feature.announcement.AppErrorSnackbarEffect +import io.github.droidkaigi.confsched2022.feature.common.AppErrorSnackbarEffect import io.github.droidkaigi.confsched2022.feature.sponsors.SponsorPlan.Gold import io.github.droidkaigi.confsched2022.feature.sponsors.SponsorPlan.Platinum import io.github.droidkaigi.confsched2022.feature.sponsors.SponsorPlan.Supporter From a973259776c30b4f2cdb7a347af6005535c17cf7 Mon Sep 17 00:00:00 2001 From: todayama_r <13657682+Corvus400@users.noreply.github.com> Date: Sun, 25 Sep 2022 08:38:20 +0900 Subject: [PATCH 05/12] :wrench: Fix spotlessApply --- .../droidkaigi/confsched2022/feature/sponsors/Sponsors.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feature/sponsors/src/main/java/io/github/droidkaigi/confsched2022/feature/sponsors/Sponsors.kt b/feature/sponsors/src/main/java/io/github/droidkaigi/confsched2022/feature/sponsors/Sponsors.kt index 0f0c4afd..15085b26 100644 --- a/feature/sponsors/src/main/java/io/github/droidkaigi/confsched2022/feature/sponsors/Sponsors.kt +++ b/feature/sponsors/src/main/java/io/github/droidkaigi/confsched2022/feature/sponsors/Sponsors.kt @@ -224,4 +224,4 @@ private fun SponsorDivider() { modifier = Modifier.padding(vertical = 8.dp, horizontal = 16.dp), color = MaterialTheme.colorScheme.outline ) -} \ No newline at end of file +} From 68bf0ec3a8345317c87bf6b2dbe714423a8408ab Mon Sep 17 00:00:00 2001 From: todayama_r <13657682+Corvus400@users.noreply.github.com> Date: Sun, 25 Sep 2022 09:04:25 +0900 Subject: [PATCH 06/12] :recycle: Update Introduce error handring to search --- .../confsched2022/feature/sessions/Search.kt | 24 ++++++++++- .../feature/sessions/SearchUiModel.kt | 4 +- .../feature/sessions/SearchViewModel.kt | 42 ++++++++++++++----- 3 files changed, 57 insertions(+), 13 deletions(-) diff --git a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/Search.kt b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/Search.kt index 8b955790..45dc938f 100644 --- a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/Search.kt +++ b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/Search.kt @@ -35,6 +35,7 @@ import androidx.compose.material3.Divider import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Text import androidx.compose.material3.TextFieldDefaults import androidx.compose.material3.TopAppBar @@ -69,6 +70,7 @@ import dev.icerock.moko.resources.compose.stringResource import io.github.droidkaigi.confsched2022.designsystem.components.KaigiScaffold import io.github.droidkaigi.confsched2022.designsystem.theme.KaigiTheme import io.github.droidkaigi.confsched2022.designsystem.theme.Typography +import io.github.droidkaigi.confsched2022.feature.announcement.AppErrorSnackbarEffect import io.github.droidkaigi.confsched2022.model.DroidKaigi2022Day import io.github.droidkaigi.confsched2022.model.DroidKaigiSchedule import io.github.droidkaigi.confsched2022.model.Filters @@ -165,6 +167,8 @@ fun SearchRoot( viewModel.onFilterFavoritesToggle() }, onBackIconClick = onBackIconClick, + onRetryButtonClick = { viewModel.onRetryButtonClick() }, + onAppErrorNotified = { viewModel.onAppErrorNotified() }, onSearchTextAreaClicked = { viewModel.onSearchTextAreaClicked() } @@ -182,10 +186,15 @@ private fun SearchScreen( onFavoritesToggleClicked: () -> Unit, onSearchTextAreaClicked: () -> Unit, onBackIconClick: () -> Unit, + onRetryButtonClick: () -> Unit, + onAppErrorNotified: () -> Unit, modifier: Modifier = Modifier, ) { val searchWord = rememberSaveable { mutableStateOf("") } + val snackbarHostState = remember { SnackbarHostState() } + KaigiScaffold( + snackbarHostState = snackbarHostState, modifier = modifier, topBar = { if (uiModel.state is Success) { @@ -198,11 +207,19 @@ private fun SearchScreen( } }, content = { + AppErrorSnackbarEffect( + appError = uiModel.appError, + snackBarHostState = snackbarHostState, + onAppErrorNotified = onAppErrorNotified, + onRetryButtonClick = onRetryButtonClick + ) Column( modifier = Modifier.padding(paddingValues = it) ) { when (uiModel.state) { - is Error -> TODO() + is Error -> { + // Do nothing + } is Success -> { SearchFilter( modifier = Modifier @@ -504,7 +521,8 @@ fun SearchScreenPreview() { uiModel = SearchUiModel( filter = SearchFilterUiModel(), filterSheetState = SearchFilterSheetState.Hide, - state = Success(DroidKaigiSchedule.fake()) + state = Success(DroidKaigiSchedule.fake()), + appError = null, ), onItemClick = {}, onBookMarkClick = { _, _ -> }, @@ -512,6 +530,8 @@ fun SearchScreenPreview() { onFavoritesToggleClicked = {}, onDayFilterClicked = {}, onCategoriesFilteredClicked = {}, + onRetryButtonClick = {}, + onAppErrorNotified = {}, onSearchTextAreaClicked = {}, ) } diff --git a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/SearchUiModel.kt b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/SearchUiModel.kt index efee7023..9e1c0c28 100644 --- a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/SearchUiModel.kt +++ b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/SearchUiModel.kt @@ -1,5 +1,6 @@ package io.github.droidkaigi.confsched2022.feature.sessions +import io.github.droidkaigi.confsched2022.model.AppError import io.github.droidkaigi.confsched2022.model.DroidKaigi2022Day import io.github.droidkaigi.confsched2022.model.DroidKaigiSchedule import io.github.droidkaigi.confsched2022.model.TimetableCategory @@ -8,7 +9,8 @@ import io.github.droidkaigi.confsched2022.ui.UiLoadState data class SearchUiModel( val filter: SearchFilterUiModel, val filterSheetState: SearchFilterSheetState, - val state: UiLoadState + val state: UiLoadState, + val appError: AppError? ) data class SearchFilterUiModel( diff --git a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/SearchViewModel.kt b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/SearchViewModel.kt index e909e0c4..5278609d 100644 --- a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/SearchViewModel.kt +++ b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/SearchViewModel.kt @@ -6,12 +6,14 @@ import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import app.cash.molecule.AndroidUiDispatcher import app.cash.molecule.RecompositionClock.ContextClock import co.touchlab.kermit.Logger import dagger.hilt.android.lifecycle.HiltViewModel +import io.github.droidkaigi.confsched2022.model.AppError import io.github.droidkaigi.confsched2022.model.DroidKaigi2022Day import io.github.droidkaigi.confsched2022.model.Filters import io.github.droidkaigi.confsched2022.model.SessionsRepository @@ -32,18 +34,17 @@ class SearchViewModel @Inject constructor( private val sessionsRepository: SessionsRepository, sessionsZipline: SessionsZipline ) : ViewModel() { - private val moleculeScope = - CoroutineScope(viewModelScope.coroutineContext + AndroidUiDispatcher.Main) - - val uiModel: State - private val filters = mutableStateOf(Filters()) private val filterSheetState = mutableStateOf( SearchFilterSheetState.Hide ) + private var appError by mutableStateOf(null) + + val uiModel: State = run { + val moleculeScope = + CoroutineScope(viewModelScope.coroutineContext + AndroidUiDispatcher.Main) - init { val ziplineScheduleModifierFlow = sessionsZipline.timetableModifier() val sessionScheduleFlow = sessionsRepository.droidKaigiScheduleFlow() @@ -59,10 +60,8 @@ class SearchViewModel @Inject constructor( schedule } }.asLoadState() - - uiModel = moleculeScope.moleculeComposeState(clock = ContextClock) { + moleculeScope.moleculeComposeState(clock = ContextClock) { val schedule by scheduleFlow.collectAsState(initial = UiLoadState.Loading) - val filteredSchedule by remember(filters) { derivedStateOf { schedule.mapSuccess { it.filtered(filters.value) } @@ -76,7 +75,8 @@ class SearchViewModel @Inject constructor( isFavoritesOn = filters.value.filterFavorite ), filterSheetState = filterSheetState.value, - state = filteredSchedule + state = filteredSchedule, + appError = appError, ) } } @@ -142,4 +142,26 @@ class SearchViewModel @Inject constructor( fun onSearchTextAreaClicked() { onFilterSheetDismissed() } + + init { + refresh() + } + + fun onRetryButtonClick() { + refresh() + } + + private fun refresh() { + viewModelScope.launch { + try { + sessionsRepository.refresh() + } catch (e: AppError) { + appError = e + } + } + } + + fun onAppErrorNotified() { + appError = null + } } From 60123dfff1c3f71e8222c644ef0d586072e9bac8 Mon Sep 17 00:00:00 2001 From: todayama_r <13657682+Corvus400@users.noreply.github.com> Date: Sun, 25 Sep 2022 09:30:50 +0900 Subject: [PATCH 07/12] :recycle: Update Introduce error handring to sessiondetail --- .../feature/sessions/SessionDetail.kt | 26 +++++++++++-- .../feature/sessions/SessionDetailUiModel.kt | 6 ++- .../sessions/SessionDetailViewModel.kt | 39 ++++++++++++++++--- 3 files changed, 60 insertions(+), 11 deletions(-) diff --git a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/SessionDetail.kt b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/SessionDetail.kt index d4880add..36fc5d92 100644 --- a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/SessionDetail.kt +++ b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/SessionDetail.kt @@ -24,6 +24,7 @@ import androidx.compose.material3.FloatingActionButtonDefaults import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults @@ -59,6 +60,7 @@ import io.github.droidkaigi.confsched2022.designsystem.components.KaigiScaffold import io.github.droidkaigi.confsched2022.designsystem.components.KaigiTag import io.github.droidkaigi.confsched2022.designsystem.theme.KaigiTheme import io.github.droidkaigi.confsched2022.designsystem.theme.TimetableItemColor +import io.github.droidkaigi.confsched2022.feature.announcement.AppErrorSnackbarEffect import io.github.droidkaigi.confsched2022.model.Lang import io.github.droidkaigi.confsched2022.model.MultiLangText import io.github.droidkaigi.confsched2022.model.TimetableAsset @@ -97,6 +99,8 @@ fun SessionDetailScreenRoot( SessionDetailScreen( modifier = modifier, uiModel = uiModel, + onRetryButtonClick = { viewModel.onRetryButtonClick() }, + onAppErrorNotified = { viewModel.onAppErrorNotified() }, onBackIconClick = onBackIconClick, onFavoriteClick = { currentFavorite -> viewModel.onFavoriteToggle(timetableItemId, currentFavorite) @@ -147,6 +151,8 @@ fun SessionDetailTopAppBar( @Composable fun SessionDetailScreen( uiModel: SessionDetailUiModel, + onRetryButtonClick: () -> Unit, + onAppErrorNotified: () -> Unit, modifier: Modifier = Modifier, onBackIconClick: () -> Unit = {}, onFavoriteClick: (Boolean) -> Unit = {}, @@ -154,10 +160,11 @@ fun SessionDetailScreen( onNavigateFloorMapClick: () -> Unit = {}, onRegisterCalendarClick: (TimetableItem) -> Unit = {}, ) { - val uiState = uiModel.state + val snackbarHostState = remember { SnackbarHostState() } KaigiScaffold( + snackbarHostState = snackbarHostState, topBar = { SessionDetailTopAppBar( onBackIconClick = onBackIconClick, @@ -178,9 +185,17 @@ fun SessionDetailScreen( } }, ) { innerPadding -> + AppErrorSnackbarEffect( + appError = uiModel.appError, + snackBarHostState = snackbarHostState, + onAppErrorNotified = onAppErrorNotified, + onRetryButtonClick = onRetryButtonClick + ) Box(modifier = Modifier.padding(innerPadding)) { when (uiState) { - is Error -> TODO() + is Error -> { + // Do nothing + } Loading -> Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { CircularProgressIndicator() @@ -635,8 +650,11 @@ fun PreviewSessionDetailScreen() { KaigiTheme { SessionDetailScreen( uiModel = SessionDetailUiModel( - Success(TimetableItemWithFavorite.fake()) - ) + state = Success(TimetableItemWithFavorite.fake()), + appError = null, + ), + onRetryButtonClick = {}, + onAppErrorNotified = {}, ) } } diff --git a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/SessionDetailUiModel.kt b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/SessionDetailUiModel.kt index 2d436279..91987c20 100644 --- a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/SessionDetailUiModel.kt +++ b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/SessionDetailUiModel.kt @@ -1,6 +1,10 @@ package io.github.droidkaigi.confsched2022.feature.sessions +import io.github.droidkaigi.confsched2022.model.AppError import io.github.droidkaigi.confsched2022.model.TimetableItemWithFavorite import io.github.droidkaigi.confsched2022.ui.UiLoadState -data class SessionDetailUiModel(val state: UiLoadState) +data class SessionDetailUiModel( + val state: UiLoadState, + val appError: AppError? +) diff --git a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/SessionDetailViewModel.kt b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/SessionDetailViewModel.kt index 54952434..ad7b4d9c 100644 --- a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/SessionDetailViewModel.kt +++ b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/SessionDetailViewModel.kt @@ -3,12 +3,15 @@ package io.github.droidkaigi.confsched2022.feature.sessions import androidx.compose.runtime.State import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import app.cash.molecule.AndroidUiDispatcher import app.cash.molecule.RecompositionClock.ContextClock import dagger.hilt.android.lifecycle.HiltViewModel +import io.github.droidkaigi.confsched2022.model.AppError import io.github.droidkaigi.confsched2022.model.SessionsRepository import io.github.droidkaigi.confsched2022.model.TimetableItemId import io.github.droidkaigi.confsched2022.ui.UiLoadState @@ -30,16 +33,22 @@ class SessionDetailViewModel @Inject constructor( private val timetableItemId: TimetableItemId = TimetableItemId(requireNotNull(savedStateHandle.get("id"))) - val uiModel: State + private var appError by mutableStateOf(null) - init { - val timetableItemFlow = - sessionsRepository.timetableItemFlow(timetableItemId).asLoadState() + private val timetableItemFlow = + sessionsRepository.timetableItemFlow(timetableItemId).asLoadState() - uiModel = moleculeScope.moleculeComposeState(clock = ContextClock) { + val uiModel: State = + moleculeScope.moleculeComposeState(clock = ContextClock) { val timetableItem by timetableItemFlow.collectAsState(initial = UiLoadState.Loading) - SessionDetailUiModel(timetableItem) + SessionDetailUiModel( + state = timetableItem, + appError = appError + ) } + + init { + refresh() } fun onFavoriteToggle(sessionId: TimetableItemId, currentIsFavorite: Boolean) { @@ -49,4 +58,22 @@ class SessionDetailViewModel @Inject constructor( ) } } + + fun onRetryButtonClick() { + refresh() + } + + private fun refresh() { + viewModelScope.launch { + try { + sessionsRepository.refresh() + } catch (e: AppError) { + appError = e + } + } + } + + fun onAppErrorNotified() { + appError = null + } } From a5d4c97f6be34444d93891831552b4389dd326a7 Mon Sep 17 00:00:00 2001 From: todayama_r <13657682+Corvus400@users.noreply.github.com> Date: Sun, 25 Sep 2022 09:35:39 +0900 Subject: [PATCH 08/12] :memo: Change Moved the AppErrorSnackbarEffect class package to common. --- .../feature/{announcement => common}/AppErrorSnackbarEffect.kt | 2 +- .../confsched2022/feature/announcement/Announcements.kt | 1 + .../github/droidkaigi/confsched2022/feature/sessions/Search.kt | 2 +- .../droidkaigi/confsched2022/feature/sessions/Sessions.kt | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) rename core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/{announcement => common}/AppErrorSnackbarEffect.kt (94%) diff --git a/core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/AppErrorSnackbarEffect.kt b/core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/common/AppErrorSnackbarEffect.kt similarity index 94% rename from core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/AppErrorSnackbarEffect.kt rename to core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/common/AppErrorSnackbarEffect.kt index 3d097df6..541924d6 100644 --- a/core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/AppErrorSnackbarEffect.kt +++ b/core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/common/AppErrorSnackbarEffect.kt @@ -1,4 +1,4 @@ -package io.github.droidkaigi.confsched2022.feature.announcement +package io.github.droidkaigi.confsched2022.feature.common import androidx.compose.material3.SnackbarDuration.Long import androidx.compose.material3.SnackbarHostState diff --git a/feature/announcement/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/Announcements.kt b/feature/announcement/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/Announcements.kt index 82547aa8..4a895143 100644 --- a/feature/announcement/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/Announcements.kt +++ b/feature/announcement/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/Announcements.kt @@ -37,6 +37,7 @@ import io.github.droidkaigi.confsched2022.designsystem.components.KaigiScaffold import io.github.droidkaigi.confsched2022.designsystem.components.KaigiTopAppBar import io.github.droidkaigi.confsched2022.designsystem.theme.KaigiColors import io.github.droidkaigi.confsched2022.designsystem.theme.KaigiTheme +import io.github.droidkaigi.confsched2022.feature.common.AppErrorSnackbarEffect import io.github.droidkaigi.confsched2022.model.AnnouncementsByDate import io.github.droidkaigi.confsched2022.model.fakes import io.github.droidkaigi.confsched2022.strings.Strings diff --git a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/Search.kt b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/Search.kt index 45dc938f..e2899494 100644 --- a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/Search.kt +++ b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/Search.kt @@ -70,7 +70,7 @@ import dev.icerock.moko.resources.compose.stringResource import io.github.droidkaigi.confsched2022.designsystem.components.KaigiScaffold import io.github.droidkaigi.confsched2022.designsystem.theme.KaigiTheme import io.github.droidkaigi.confsched2022.designsystem.theme.Typography -import io.github.droidkaigi.confsched2022.feature.announcement.AppErrorSnackbarEffect +import io.github.droidkaigi.confsched2022.feature.common.AppErrorSnackbarEffect import io.github.droidkaigi.confsched2022.model.DroidKaigi2022Day import io.github.droidkaigi.confsched2022.model.DroidKaigiSchedule import io.github.droidkaigi.confsched2022.model.Filters diff --git a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/Sessions.kt b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/Sessions.kt index eca80447..319d388e 100644 --- a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/Sessions.kt +++ b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/Sessions.kt @@ -66,7 +66,7 @@ import dev.icerock.moko.resources.compose.stringResource import io.github.droidkaigi.confsched2022.designsystem.components.KaigiScaffold import io.github.droidkaigi.confsched2022.designsystem.components.KaigiTopAppBar import io.github.droidkaigi.confsched2022.designsystem.theme.KaigiTheme -import io.github.droidkaigi.confsched2022.feature.announcement.AppErrorSnackbarEffect +import io.github.droidkaigi.confsched2022.feature.common.AppErrorSnackbarEffect import io.github.droidkaigi.confsched2022.model.DroidKaigi2022Day import io.github.droidkaigi.confsched2022.model.DroidKaigiSchedule import io.github.droidkaigi.confsched2022.model.TimetableItemId From fe9d2d0c4379a11ce47ea6dc42948c0fd000cad4 Mon Sep 17 00:00:00 2001 From: todayama_r <13657682+Corvus400@users.noreply.github.com> Date: Sun, 25 Sep 2022 09:36:09 +0900 Subject: [PATCH 09/12] :memo: Change Moved the AppErrorSnackbarEffect class package to common. --- .../feature/{announcement => common}/AppErrorSnackbarEffect.kt | 2 +- .../confsched2022/feature/announcement/Announcements.kt | 1 + .../droidkaigi/confsched2022/feature/sessions/SessionDetail.kt | 2 +- .../droidkaigi/confsched2022/feature/sessions/Sessions.kt | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) rename core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/{announcement => common}/AppErrorSnackbarEffect.kt (94%) diff --git a/core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/AppErrorSnackbarEffect.kt b/core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/common/AppErrorSnackbarEffect.kt similarity index 94% rename from core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/AppErrorSnackbarEffect.kt rename to core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/common/AppErrorSnackbarEffect.kt index 3d097df6..541924d6 100644 --- a/core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/AppErrorSnackbarEffect.kt +++ b/core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/common/AppErrorSnackbarEffect.kt @@ -1,4 +1,4 @@ -package io.github.droidkaigi.confsched2022.feature.announcement +package io.github.droidkaigi.confsched2022.feature.common import androidx.compose.material3.SnackbarDuration.Long import androidx.compose.material3.SnackbarHostState diff --git a/feature/announcement/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/Announcements.kt b/feature/announcement/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/Announcements.kt index 82547aa8..4a895143 100644 --- a/feature/announcement/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/Announcements.kt +++ b/feature/announcement/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/Announcements.kt @@ -37,6 +37,7 @@ import io.github.droidkaigi.confsched2022.designsystem.components.KaigiScaffold import io.github.droidkaigi.confsched2022.designsystem.components.KaigiTopAppBar import io.github.droidkaigi.confsched2022.designsystem.theme.KaigiColors import io.github.droidkaigi.confsched2022.designsystem.theme.KaigiTheme +import io.github.droidkaigi.confsched2022.feature.common.AppErrorSnackbarEffect import io.github.droidkaigi.confsched2022.model.AnnouncementsByDate import io.github.droidkaigi.confsched2022.model.fakes import io.github.droidkaigi.confsched2022.strings.Strings diff --git a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/SessionDetail.kt b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/SessionDetail.kt index 36fc5d92..c2a49ef1 100644 --- a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/SessionDetail.kt +++ b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/SessionDetail.kt @@ -60,7 +60,7 @@ import io.github.droidkaigi.confsched2022.designsystem.components.KaigiScaffold import io.github.droidkaigi.confsched2022.designsystem.components.KaigiTag import io.github.droidkaigi.confsched2022.designsystem.theme.KaigiTheme import io.github.droidkaigi.confsched2022.designsystem.theme.TimetableItemColor -import io.github.droidkaigi.confsched2022.feature.announcement.AppErrorSnackbarEffect +import io.github.droidkaigi.confsched2022.feature.common.AppErrorSnackbarEffect import io.github.droidkaigi.confsched2022.model.Lang import io.github.droidkaigi.confsched2022.model.MultiLangText import io.github.droidkaigi.confsched2022.model.TimetableAsset diff --git a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/Sessions.kt b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/Sessions.kt index eca80447..319d388e 100644 --- a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/Sessions.kt +++ b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/Sessions.kt @@ -66,7 +66,7 @@ import dev.icerock.moko.resources.compose.stringResource import io.github.droidkaigi.confsched2022.designsystem.components.KaigiScaffold import io.github.droidkaigi.confsched2022.designsystem.components.KaigiTopAppBar import io.github.droidkaigi.confsched2022.designsystem.theme.KaigiTheme -import io.github.droidkaigi.confsched2022.feature.announcement.AppErrorSnackbarEffect +import io.github.droidkaigi.confsched2022.feature.common.AppErrorSnackbarEffect import io.github.droidkaigi.confsched2022.model.DroidKaigi2022Day import io.github.droidkaigi.confsched2022.model.DroidKaigiSchedule import io.github.droidkaigi.confsched2022.model.TimetableItemId From 35c8e5a59b6b413e0f931718cb7c4bc27d23711c Mon Sep 17 00:00:00 2001 From: todayama_r <13657682+Corvus400@users.noreply.github.com> Date: Sun, 25 Sep 2022 09:58:42 +0900 Subject: [PATCH 10/12] :recycle: Update Introduce error handring to staff --- .../data/staff/DataStaffRepository.kt | 21 ++++++---- .../data/staff/FakeStaffRepository.kt | 3 ++ .../confsched2022/model/StaffRepository.kt | 2 + .../confsched2022/feature/staff/Staff.kt | 33 +++++++++++++-- .../feature/staff/StaffUiModel.kt | 6 ++- .../feature/staff/StaffViewModel.kt | 41 ++++++++++++++++--- 6 files changed, 89 insertions(+), 17 deletions(-) diff --git a/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/staff/DataStaffRepository.kt b/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/staff/DataStaffRepository.kt index 3a3d3749..b45bdaa0 100644 --- a/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/staff/DataStaffRepository.kt +++ b/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/staff/DataStaffRepository.kt @@ -3,22 +3,29 @@ package io.github.droidkaigi.confsched2022.data.staff import io.github.droidkaigi.confsched2022.model.Staff import io.github.droidkaigi.confsched2022.model.StaffRepository import kotlinx.collections.immutable.PersistentList +import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toPersistentList -import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.callbackFlow public class DataStaffRepository( private val staffApi: StaffApi ) : StaffRepository { + private val staffStateFlow = + MutableStateFlow>(persistentListOf()) + override fun staff(): Flow> { return callbackFlow { - send( - staffApi - .staff() - .toPersistentList() - ) - awaitClose { } + staffStateFlow.collect { + send(it) + } } } + + override suspend fun refresh() { + staffStateFlow.value = staffApi + .staff() + .toPersistentList() + } } diff --git a/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/staff/FakeStaffRepository.kt b/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/staff/FakeStaffRepository.kt index dffaff3f..d40e85ee 100644 --- a/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/staff/FakeStaffRepository.kt +++ b/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/staff/FakeStaffRepository.kt @@ -12,4 +12,7 @@ public class FakeStaffRepository : StaffRepository { override fun staff(): Flow> { return flowOf(staff) } + + override suspend fun refresh() { + } } diff --git a/core/model/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/model/StaffRepository.kt b/core/model/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/model/StaffRepository.kt index 8e11285d..d08e13a0 100644 --- a/core/model/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/model/StaffRepository.kt +++ b/core/model/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/model/StaffRepository.kt @@ -5,4 +5,6 @@ import kotlinx.coroutines.flow.Flow public interface StaffRepository { public fun staff(): Flow> + + public suspend fun refresh() } diff --git a/feature/staff/src/main/java/io/github/droidkaigi/confsched2022/feature/staff/Staff.kt b/feature/staff/src/main/java/io/github/droidkaigi/confsched2022/feature/staff/Staff.kt index 3590e8bf..ae564560 100644 --- a/feature/staff/src/main/java/io/github/droidkaigi/confsched2022/feature/staff/Staff.kt +++ b/feature/staff/src/main/java/io/github/droidkaigi/confsched2022/feature/staff/Staff.kt @@ -7,9 +7,11 @@ 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.SnackbarHostState import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview @@ -19,6 +21,7 @@ import io.github.droidkaigi.confsched2022.designsystem.components.KaigiScaffold import io.github.droidkaigi.confsched2022.designsystem.components.KaigiTopAppBar import io.github.droidkaigi.confsched2022.designsystem.components.UsernameRow import io.github.droidkaigi.confsched2022.designsystem.theme.KaigiTheme +import io.github.droidkaigi.confsched2022.feature.announcement.AppErrorSnackbarEffect import io.github.droidkaigi.confsched2022.model.Staff import io.github.droidkaigi.confsched2022.model.fakes import io.github.droidkaigi.confsched2022.strings.Strings @@ -35,7 +38,15 @@ fun StaffScreenRoot( onLinkClick: (url: String, packageName: String?) -> Unit = { _, _ -> } ) { val uiModel by viewModel.uiModel - Staff(uiModel, showNavigationIcon, onNavigationIconClick, onLinkClick, modifier) + Staff( + uiModel = uiModel, + showNavigationIcon = showNavigationIcon, + onNavigationIconClick = onNavigationIconClick, + onRetryButtonClick = { viewModel.onRetryButtonClick() }, + onAppErrorNotified = { viewModel.onAppErrorNotified() }, + onLinkClick = onLinkClick, + modifier = modifier + ) } @Composable @@ -43,10 +54,15 @@ fun Staff( uiModel: StaffUiModel, showNavigationIcon: Boolean, onNavigationIconClick: () -> Unit, + onRetryButtonClick: () -> Unit, + onAppErrorNotified: () -> Unit, onLinkClick: (url: String, packageName: String?) -> Unit, modifier: Modifier = Modifier ) { + val snackbarHostState = remember { SnackbarHostState() } + KaigiScaffold( + snackbarHostState = snackbarHostState, topBar = { KaigiTopAppBar( showNavigationIcon = showNavigationIcon, @@ -59,9 +75,17 @@ fun Staff( ) } ) { innerPadding -> + AppErrorSnackbarEffect( + appError = uiModel.appError, + snackBarHostState = snackbarHostState, + onAppErrorNotified = onAppErrorNotified, + onRetryButtonClick = onRetryButtonClick + ) Box(modifier = Modifier.padding(innerPadding)) { when (uiModel.state) { - is Error -> TODO() + is Error -> { + // Do nothing + } is Loading -> Box( modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center, @@ -97,10 +121,13 @@ fun StaffPreview() { uiModel = StaffUiModel( state = Success( Staff.fakes() - ) + ), + appError = null, ), showNavigationIcon = true, onNavigationIconClick = {}, + onRetryButtonClick = {}, + onAppErrorNotified = {}, onLinkClick = { _, _ -> }, ) } diff --git a/feature/staff/src/main/java/io/github/droidkaigi/confsched2022/feature/staff/StaffUiModel.kt b/feature/staff/src/main/java/io/github/droidkaigi/confsched2022/feature/staff/StaffUiModel.kt index 9fb9d4e4..b8c0836f 100644 --- a/feature/staff/src/main/java/io/github/droidkaigi/confsched2022/feature/staff/StaffUiModel.kt +++ b/feature/staff/src/main/java/io/github/droidkaigi/confsched2022/feature/staff/StaffUiModel.kt @@ -1,7 +1,11 @@ package io.github.droidkaigi.confsched2022.feature.staff +import io.github.droidkaigi.confsched2022.model.AppError import io.github.droidkaigi.confsched2022.model.Staff import io.github.droidkaigi.confsched2022.ui.UiLoadState import kotlinx.collections.immutable.PersistentList -data class StaffUiModel(val state: UiLoadState>) +data class StaffUiModel( + val state: UiLoadState>, + val appError: AppError?, +) diff --git a/feature/staff/src/main/java/io/github/droidkaigi/confsched2022/feature/staff/StaffViewModel.kt b/feature/staff/src/main/java/io/github/droidkaigi/confsched2022/feature/staff/StaffViewModel.kt index 3f1e5e17..7cc69321 100644 --- a/feature/staff/src/main/java/io/github/droidkaigi/confsched2022/feature/staff/StaffViewModel.kt +++ b/feature/staff/src/main/java/io/github/droidkaigi/confsched2022/feature/staff/StaffViewModel.kt @@ -3,33 +3,62 @@ package io.github.droidkaigi.confsched2022.feature.staff import androidx.compose.runtime.State import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import app.cash.molecule.AndroidUiDispatcher import app.cash.molecule.RecompositionClock.ContextClock import dagger.hilt.android.lifecycle.HiltViewModel +import io.github.droidkaigi.confsched2022.model.AppError import io.github.droidkaigi.confsched2022.model.StaffRepository import io.github.droidkaigi.confsched2022.ui.UiLoadState.Loading import io.github.droidkaigi.confsched2022.ui.asLoadState import io.github.droidkaigi.confsched2022.ui.moleculeComposeState import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel class StaffViewModel @Inject constructor( - staffRepository: StaffRepository, + private val staffRepository: StaffRepository, ) : ViewModel() { private val moleculeScope = CoroutineScope(viewModelScope.coroutineContext + AndroidUiDispatcher.Main) - val uiModel: State + private val staffFlow = staffRepository + .staff() + .asLoadState() + + private var appError by mutableStateOf(null) + + val uiModel: State = moleculeScope.moleculeComposeState(clock = ContextClock) { + val staffState by staffFlow.collectAsState(initial = Loading) + StaffUiModel( + state = staffState, + appError = appError, + ) + } init { - val dataFlow = staffRepository.staff().asLoadState() + refresh() + } - uiModel = moleculeScope.moleculeComposeState(clock = ContextClock) { - val data by dataFlow.collectAsState(initial = Loading) - StaffUiModel(data) + fun onRetryButtonClick() { + refresh() + } + + private fun refresh() { + viewModelScope.launch { + try { + staffRepository.refresh() + } catch (e: AppError) { + appError = e + } } } + + fun onAppErrorNotified() { + appError = null + } } From feea7db2bb8e4a6358875e38926ad78c3cd38313 Mon Sep 17 00:00:00 2001 From: todayama_r <13657682+Corvus400@users.noreply.github.com> Date: Sun, 25 Sep 2022 09:59:05 +0900 Subject: [PATCH 11/12] :memo: Change Moved the AppErrorSnackbarEffect class package to common. --- .../feature/{announcement => common}/AppErrorSnackbarEffect.kt | 2 +- .../confsched2022/feature/announcement/Announcements.kt | 1 + .../droidkaigi/confsched2022/feature/sessions/Sessions.kt | 2 +- .../io/github/droidkaigi/confsched2022/feature/staff/Staff.kt | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) rename core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/{announcement => common}/AppErrorSnackbarEffect.kt (94%) diff --git a/core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/AppErrorSnackbarEffect.kt b/core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/common/AppErrorSnackbarEffect.kt similarity index 94% rename from core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/AppErrorSnackbarEffect.kt rename to core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/common/AppErrorSnackbarEffect.kt index 3d097df6..541924d6 100644 --- a/core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/AppErrorSnackbarEffect.kt +++ b/core/ui/src/main/java/io/github/droidkaigi/confsched2022/feature/common/AppErrorSnackbarEffect.kt @@ -1,4 +1,4 @@ -package io.github.droidkaigi.confsched2022.feature.announcement +package io.github.droidkaigi.confsched2022.feature.common import androidx.compose.material3.SnackbarDuration.Long import androidx.compose.material3.SnackbarHostState diff --git a/feature/announcement/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/Announcements.kt b/feature/announcement/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/Announcements.kt index 82547aa8..4a895143 100644 --- a/feature/announcement/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/Announcements.kt +++ b/feature/announcement/src/main/java/io/github/droidkaigi/confsched2022/feature/announcement/Announcements.kt @@ -37,6 +37,7 @@ import io.github.droidkaigi.confsched2022.designsystem.components.KaigiScaffold import io.github.droidkaigi.confsched2022.designsystem.components.KaigiTopAppBar import io.github.droidkaigi.confsched2022.designsystem.theme.KaigiColors import io.github.droidkaigi.confsched2022.designsystem.theme.KaigiTheme +import io.github.droidkaigi.confsched2022.feature.common.AppErrorSnackbarEffect import io.github.droidkaigi.confsched2022.model.AnnouncementsByDate import io.github.droidkaigi.confsched2022.model.fakes import io.github.droidkaigi.confsched2022.strings.Strings diff --git a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/Sessions.kt b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/Sessions.kt index eca80447..319d388e 100644 --- a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/Sessions.kt +++ b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2022/feature/sessions/Sessions.kt @@ -66,7 +66,7 @@ import dev.icerock.moko.resources.compose.stringResource import io.github.droidkaigi.confsched2022.designsystem.components.KaigiScaffold import io.github.droidkaigi.confsched2022.designsystem.components.KaigiTopAppBar import io.github.droidkaigi.confsched2022.designsystem.theme.KaigiTheme -import io.github.droidkaigi.confsched2022.feature.announcement.AppErrorSnackbarEffect +import io.github.droidkaigi.confsched2022.feature.common.AppErrorSnackbarEffect import io.github.droidkaigi.confsched2022.model.DroidKaigi2022Day import io.github.droidkaigi.confsched2022.model.DroidKaigiSchedule import io.github.droidkaigi.confsched2022.model.TimetableItemId diff --git a/feature/staff/src/main/java/io/github/droidkaigi/confsched2022/feature/staff/Staff.kt b/feature/staff/src/main/java/io/github/droidkaigi/confsched2022/feature/staff/Staff.kt index ae564560..02473ecc 100644 --- a/feature/staff/src/main/java/io/github/droidkaigi/confsched2022/feature/staff/Staff.kt +++ b/feature/staff/src/main/java/io/github/droidkaigi/confsched2022/feature/staff/Staff.kt @@ -21,7 +21,7 @@ import io.github.droidkaigi.confsched2022.designsystem.components.KaigiScaffold import io.github.droidkaigi.confsched2022.designsystem.components.KaigiTopAppBar import io.github.droidkaigi.confsched2022.designsystem.components.UsernameRow import io.github.droidkaigi.confsched2022.designsystem.theme.KaigiTheme -import io.github.droidkaigi.confsched2022.feature.announcement.AppErrorSnackbarEffect +import io.github.droidkaigi.confsched2022.feature.common.AppErrorSnackbarEffect import io.github.droidkaigi.confsched2022.model.Staff import io.github.droidkaigi.confsched2022.model.fakes import io.github.droidkaigi.confsched2022.strings.Strings From 7a53209fda8d38080caa49f8ddd785ddc82a132d Mon Sep 17 00:00:00 2001 From: ryoya ito Date: Wed, 28 Sep 2022 00:19:04 +0900 Subject: [PATCH 12/12] Apply to iOS --- app-ios/Sources/ContributorFeature/ContributorView.swift | 1 + app-ios/Sources/SponsorFeature/SponsorView.swift | 1 + app-ios/Sources/StaffFeature/StaffView.swift | 1 + 3 files changed, 3 insertions(+) diff --git a/app-ios/Sources/ContributorFeature/ContributorView.swift b/app-ios/Sources/ContributorFeature/ContributorView.swift index 9fb61484..6a6859db 100644 --- a/app-ios/Sources/ContributorFeature/ContributorView.swift +++ b/app-ios/Sources/ContributorFeature/ContributorView.swift @@ -29,6 +29,7 @@ public let contributorReducer = Reducer { s switch action { case .refresh: return .run { @MainActor subscriber in + try await environment.staffRepository.refresh() for try await result: [Staff] in environment.staffRepository.staff().stream() { await subscriber.send( .refreshResponse(