diff --git a/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/other/MaterialSymbols.kt b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/other/MaterialSymbols.kt new file mode 100644 index 0000000..18c219f --- /dev/null +++ b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/other/MaterialSymbols.kt @@ -0,0 +1,124 @@ +package dev.datlag.aniflow.other + +import androidx.compose.material.icons.materialIcon +import androidx.compose.material.icons.materialPath +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.* +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.graphics.vector.path +import androidx.compose.ui.unit.dp + +data object MaterialSymbols { + + data object Rounded { + private var _home: ImageVector? = null + + val Home: ImageVector + get() { + return _home ?: ImageVector.Builder( + name = "home", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 40f, + viewportHeight = 40f + ).apply { + path( + fill = SolidColor(Color.Black), + fillAlpha = 1f, + stroke = null, + strokeAlpha = 1f, + strokeLineWidth = 1.0f, + strokeLineCap = StrokeCap.Butt, + strokeLineJoin = StrokeJoin.Miter, + strokeLineMiter = 1f, + pathFillType = PathFillType.NonZero + ) { + moveTo(9.542f, 32.125f) + horizontalLineToRelative(5.75f) + verticalLineToRelative(-10.25f) + horizontalLineToRelative(9.416f) + verticalLineToRelative(10.25f) + horizontalLineToRelative(5.75f) + verticalLineTo(16.417f) + lineTo(20f, 8.583f) + lineTo(9.542f, 16.417f) + close() + moveToRelative(0f, 2.625f) + quadToRelative(-1.084f, 0f, -1.855f, -0.771f) + quadToRelative(-0.77f, -0.771f, -0.77f, -1.854f) + verticalLineTo(16.417f) + quadToRelative(0f, -0.625f, 0.271f, -1.188f) + quadToRelative(0.27f, -0.562f, 0.77f, -0.937f) + lineToRelative(10.459f, -7.834f) + quadToRelative(0.375f, -0.25f, 0.771f, -0.375f) + quadToRelative(0.395f, -0.125f, 0.812f, -0.125f) + quadToRelative(0.417f, 0f, 0.812f, 0.125f) + quadToRelative(0.396f, 0.125f, 0.771f, 0.375f) + lineToRelative(10.459f, 7.834f) + quadToRelative(0.5f, 0.375f, 0.77f, 0.937f) + quadToRelative(0.271f, 0.563f, 0.271f, 1.188f) + verticalLineToRelative(15.708f) + quadToRelative(0f, 1.083f, -0.771f, 1.854f) + quadToRelative(-0.77f, 0.771f, -1.854f, 0.771f) + horizontalLineToRelative(-8.375f) + verticalLineTo(24.5f) + horizontalLineToRelative(-4.166f) + verticalLineToRelative(10.25f) + close() + moveTo(20f, 20.333f) + close() + } + }.build().also { _home = it } + } + } + + data object Filled { + private var _home: ImageVector? = null + + val Home: ImageVector + get() { + return _home ?: ImageVector.Builder( + name = "home", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 40.0f, + viewportHeight = 40.0f + ).apply { + path( + fill = SolidColor(Color.Black), + fillAlpha = 1f, + stroke = null, + strokeAlpha = 1f, + strokeLineWidth = 1.0f, + strokeLineCap = StrokeCap.Butt, + strokeLineJoin = StrokeJoin.Miter, + strokeLineMiter = 1f, + pathFillType = PathFillType.NonZero + ) { + moveTo(9.542f, 34.75f) + quadToRelative(-1.084f, 0f, -1.855f, -0.771f) + quadToRelative(-0.77f, -0.771f, -0.77f, -1.854f) + verticalLineTo(16.417f) + quadToRelative(0f, -0.625f, 0.271f, -1.188f) + quadToRelative(0.27f, -0.562f, 0.77f, -0.937f) + lineToRelative(10.459f, -7.834f) + quadToRelative(0.375f, -0.25f, 0.771f, -0.375f) + quadToRelative(0.395f, -0.125f, 0.812f, -0.125f) + quadToRelative(0.417f, 0f, 0.812f, 0.125f) + quadToRelative(0.396f, 0.125f, 0.771f, 0.375f) + lineToRelative(10.459f, 7.834f) + quadToRelative(0.5f, 0.375f, 0.77f, 0.937f) + quadToRelative(0.271f, 0.563f, 0.271f, 1.188f) + verticalLineToRelative(15.708f) + quadToRelative(0f, 1.083f, -0.771f, 1.854f) + quadToRelative(-0.77f, 0.771f, -1.854f, 0.771f) + horizontalLineToRelative(-7.041f) + verticalLineTo(23.208f) + horizontalLineToRelative(-6.792f) + verticalLineTo(34.75f) + close() + } + }.build().also { _home = it } + } + } +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/component/HidingNavigationBar.kt b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/component/HidingNavigationBar.kt index 65d92fd..65dfec2 100644 --- a/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/component/HidingNavigationBar.kt +++ b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/component/HidingNavigationBar.kt @@ -16,6 +16,7 @@ import androidx.compose.material.icons.outlined.Home import androidx.compose.material.icons.rounded.* import androidx.compose.material3.* import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -29,9 +30,12 @@ import dev.chrisbanes.haze.materials.HazeMaterials import dev.datlag.aniflow.LocalHaze import dev.datlag.aniflow.SharedRes import dev.datlag.aniflow.common.isScrollingUp +import dev.datlag.aniflow.other.MaterialSymbols import dev.datlag.aniflow.ui.navigation.RootConfig +import dev.datlag.tooling.decompose.lifecycle.collectAsStateWithLifecycle import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource +import kotlinx.coroutines.flow.Flow import kotlinx.serialization.Serializable import kotlinx.serialization.Transient @@ -40,6 +44,7 @@ import kotlinx.serialization.Transient fun HidingNavigationBar( visible: Boolean, selected: NavigationBarState, + loggedIn: Flow, onDiscover: () -> Unit, onHome: () -> Unit, onFavorites: () -> Unit @@ -82,6 +87,7 @@ fun HidingNavigationBar( val isFavorites = remember(selected) { selected is NavigationBarState.Favorite } + val isLoggedIn by loggedIn.collectAsStateWithLifecycle(false) NavigationBarItem( onClick = { @@ -124,6 +130,7 @@ fun HidingNavigationBar( } }, selected = isFavorites, + enabled = isLoggedIn, icon = { Icon( imageVector = selected.favoriteIcon, @@ -131,7 +138,7 @@ fun HidingNavigationBar( ) }, label = { - Text(text = stringResource(SharedRes.strings.favorites)) + Text(text = "List") } ) } @@ -174,18 +181,15 @@ sealed interface NavigationBarState { @Serializable data object Home : NavigationBarState { override val unselectedIcon: ImageVector - get() = Icons.Outlined.Home + get() = MaterialSymbols.Rounded.Home override val selectedIcon: ImageVector - get() = Icons.Rounded.Home + get() = MaterialSymbols.Filled.Home } @Serializable data object Favorite : NavigationBarState { override val unselectedIcon: ImageVector - get() = Icons.Rounded.FavoriteBorder - - override val selectedIcon: ImageVector - get() = Icons.Rounded.Favorite + get() = Icons.Rounded.Checklist } } \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/favorites/FavoritesScreen.kt b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/favorites/FavoritesScreen.kt index d4831e9..4716ce9 100644 --- a/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/favorites/FavoritesScreen.kt +++ b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/favorites/FavoritesScreen.kt @@ -4,6 +4,7 @@ import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable import dev.datlag.aniflow.ui.navigation.screen.component.HidingNavigationBar import dev.datlag.aniflow.ui.navigation.screen.component.NavigationBarState +import kotlinx.coroutines.flow.flowOf @Composable fun FavoritesScreen(component: FavoritesComponent) { @@ -12,6 +13,7 @@ fun FavoritesScreen(component: FavoritesComponent) { HidingNavigationBar( visible = true, selected = NavigationBarState.Favorite, + loggedIn = flowOf(true), onDiscover = component::viewDiscover, onHome = component::viewHome, onFavorites = { } diff --git a/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/favorites/FavoritesScreenComponent.kt b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/favorites/FavoritesScreenComponent.kt index 72cde08..4e9d7e8 100644 --- a/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/favorites/FavoritesScreenComponent.kt +++ b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/favorites/FavoritesScreenComponent.kt @@ -7,7 +7,11 @@ import com.arkivanov.decompose.ComponentContext import dev.chrisbanes.haze.HazeState import dev.datlag.aniflow.LocalHaze import dev.datlag.aniflow.common.onRender +import dev.datlag.aniflow.other.UserHelper +import dev.datlag.tooling.compose.withMainContext +import kotlinx.coroutines.flow.collectLatest import org.kodein.di.DI +import org.kodein.di.instance class FavoritesScreenComponent( componentContext: ComponentContext, @@ -16,6 +20,9 @@ class FavoritesScreenComponent( private val onHome: () -> Unit, ) : FavoritesComponent, ComponentContext by componentContext { + private val userHelper by instance() + val user = userHelper.user + @Composable override fun render() { val haze = remember { HazeState() } diff --git a/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/home/HomeScreen.kt b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/home/HomeScreen.kt index 659dbeb..4fd4969 100644 --- a/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/home/HomeScreen.kt +++ b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/home/HomeScreen.kt @@ -52,8 +52,11 @@ import dev.datlag.aniflow.ui.navigation.screen.home.component.ScheduleOverview import dev.datlag.tooling.decompose.lifecycle.collectAsStateWithLifecycle import dev.icerock.moko.resources.compose.stringResource import io.github.aakira.napier.Napier +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.mapLatest +import kotlinx.coroutines.flow.mapNotNull -@OptIn(ExperimentalMaterial3Api::class) +@OptIn(ExperimentalMaterial3Api::class, ExperimentalCoroutinesApi::class) @Composable fun HomeScreen(component: HomeComponent) { val appBarState = rememberTopAppBarState() @@ -167,6 +170,7 @@ fun HomeScreen(component: HomeComponent) { HidingNavigationBar( visible = listState.isScrollingUp() && listState.canScrollForward, selected = NavigationBarState.Home, + loggedIn = component.user.mapLatest { it != null }, onDiscover = component::viewDiscover, onHome = { }, onFavorites = component::viewFavorites diff --git a/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/home/HomeScreenComponent.kt b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/home/HomeScreenComponent.kt index 69a0e49..68a4e30 100644 --- a/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/home/HomeScreenComponent.kt +++ b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/home/HomeScreenComponent.kt @@ -18,6 +18,7 @@ import dev.datlag.aniflow.anilist.state.CollectionState import dev.datlag.aniflow.anilist.type.MediaType import dev.datlag.aniflow.common.onRender import dev.datlag.aniflow.model.coroutines.Executor +import dev.datlag.aniflow.model.mutableStateIn import dev.datlag.aniflow.other.StateSaver import dev.datlag.aniflow.other.UserHelper import dev.datlag.aniflow.settings.Settings @@ -68,24 +69,22 @@ class HomeScreenComponent( ) private val trendingRepository by instance() - override val trending: Flow = trendingRepository.trending.map { + override val trending: MutableStateFlow = trendingRepository.trending.map { StateSaver.Home.updateTrending(it) }.flowOn( context = ioDispatcher() - ).stateIn( + ).mutableStateIn( scope = stateScope, - started = SharingStarted.WhileSubscribed(), initialValue = CollectionState.None ) private val popularSeasonRepository by instance() - override val popularNow: Flow = popularSeasonRepository.popularThisSeason.map { + override val popularNow: MutableStateFlow = popularSeasonRepository.popularThisSeason.map { StateSaver.Home.updatePopularCurrent(it) }.flowOn( context = ioDispatcher() - ).stateIn( + ).mutableStateIn( scope = stateScope, - started = SharingStarted.WhileSubscribed(), initialValue = CollectionState.None ) @@ -143,6 +142,8 @@ class HomeScreenComponent( StateSaver.Home.updateAllLoading() launchIO { viewTypeExecutor.enqueue { + clearForTypeChange() + appSettings.setViewManga(false) } } @@ -152,6 +153,8 @@ class HomeScreenComponent( StateSaver.Home.updateAllLoading() launchIO { viewTypeExecutor.enqueue { + clearForTypeChange() + appSettings.setViewManga(true) } } @@ -176,4 +179,9 @@ class HomeScreenComponent( override fun clearTrace() { traceRepository.clear() } + + private suspend fun clearForTypeChange() { + trending.emit(CollectionState.None) + popularNow.emit(CollectionState.None) + } } \ No newline at end of file