Skip to content

Commit 04a864a

Browse files
committed
prepare next navigation implementation
1 parent 6fcc17a commit 04a864a

File tree

24 files changed

+139
-38
lines changed

24 files changed

+139
-38
lines changed

anilist/src/commonMain/kotlin/dev/datlag/aniflow/anilist/AiringTodayRepository.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class AiringTodayRepository(
2020
page = p,
2121
nsfw = n,
2222
)
23-
}
23+
}.distinctUntilChanged()
2424

2525
private val airingPreFilter = query.transform {
2626
return@transform emitAll(apolloClient.query(it.toGraphQL()).toFlow())

anilist/src/commonMain/kotlin/dev/datlag/aniflow/anilist/PopularNextSeasonRepository.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class PopularNextSeasonRepository(
3636
season = season,
3737
year = year
3838
)
39-
}
39+
}.distinctUntilChanged()
4040
private val fallbackQuery = query.transform {
4141
return@transform emitAll(fallbackClient.query(it.toGraphQL()).toFlow())
4242
}.mapNotNull {

anilist/src/commonMain/kotlin/dev/datlag/aniflow/anilist/PopularSeasonRepository.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class PopularSeasonRepository(
2929
type = t,
3030
nsfw = n
3131
)
32-
}
32+
}.distinctUntilChanged()
3333
private val fallbackQuery = query.transform {
3434
return@transform emitAll(fallbackClient.query(it.toGraphQL()).toFlow())
3535
}.mapNotNull {

anilist/src/commonMain/kotlin/dev/datlag/aniflow/anilist/TrendingRepository.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class TrendingRepository(
2929
type = t,
3030
nsfw = n
3131
)
32-
}
32+
}.distinctUntilChanged()
3333
private val fallbackQuery = query.transform {
3434
return@transform emitAll(fallbackClient.query(it.toGraphQL()).toFlow())
3535
}.mapNotNull {
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package dev.datlag.aniflow.ui.navigation.screen.initial.settings.component
1+
package dev.datlag.aniflow.ui.navigation.screen.settings.component
22

33
import androidx.compose.foundation.layout.Arrangement
44
import androidx.compose.foundation.layout.Row

composeApp/src/commonMain/kotlin/dev/datlag/aniflow/other/StateSaver.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,5 +90,12 @@ data object StateSaver {
9090
popularNextLoading.update { false }
9191
return state
9292
}
93+
94+
fun updateAllLoading() {
95+
airingLoading.update { true }
96+
trendingLoading.update { true }
97+
popularCurrentLoading.update { true }
98+
popularNextLoading.update { true }
99+
}
93100
}
94101
}

composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/RootComponent.kt

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,26 @@
11
package dev.datlag.aniflow.ui.navigation
22

3+
import androidx.compose.animation.core.tween
4+
import androidx.compose.foundation.gestures.Orientation
35
import androidx.compose.runtime.Composable
6+
import androidx.compose.ui.Modifier
7+
import androidx.compose.ui.layout.layout
48
import com.arkivanov.decompose.ComponentContext
59
import com.arkivanov.decompose.ExperimentalDecomposeApi
610
import com.arkivanov.decompose.extensions.compose.stack.Children
711
import com.arkivanov.decompose.extensions.compose.stack.animation.predictiveback.predictiveBackAnimation
812
import com.arkivanov.decompose.extensions.compose.stack.animation.slide
913
import com.arkivanov.decompose.extensions.compose.stack.animation.stackAnimation
14+
import com.arkivanov.decompose.extensions.compose.stack.animation.stackAnimator
1015
import com.arkivanov.decompose.router.stack.*
1116
import dev.datlag.aniflow.common.onRender
1217
import dev.datlag.aniflow.model.ifValueOrNull
1318
import dev.datlag.aniflow.other.UserHelper
1419
import dev.datlag.aniflow.ui.navigation.screen.initial.InitialScreenComponent
1520
import dev.datlag.aniflow.ui.navigation.screen.medium.MediumScreenComponent
21+
import dev.datlag.aniflow.ui.navigation.screen.settings.SettingsScreen
22+
import dev.datlag.aniflow.ui.navigation.screen.settings.SettingsScreenComponent
23+
import io.github.aakira.napier.Napier
1624
import org.kodein.di.DI
1725
import org.kodein.di.instance
1826

@@ -40,6 +48,9 @@ class RootComponent(
4048
di = di,
4149
onMediumDetails = {
4250
navigation.push(RootConfig.Details(it))
51+
},
52+
onProfile = {
53+
navigation.push(RootConfig.Settings)
4354
}
4455
)
4556
is RootConfig.Details -> MediumScreenComponent(
@@ -48,6 +59,10 @@ class RootComponent(
4859
initialMedium = rootConfig.medium,
4960
onBack = navigation::pop
5061
)
62+
is RootConfig.Settings -> SettingsScreenComponent(
63+
componentContext = componentContext,
64+
di = di
65+
)
5166
}
5267
}
5368

@@ -59,9 +74,40 @@ class RootComponent(
5974
stack = stack,
6075
animation = predictiveBackAnimation(
6176
backHandler = this.backHandler,
62-
fallbackAnimation = stackAnimation(
63-
animator = slide()
64-
),
77+
fallbackAnimation = stackAnimation { child ->
78+
when (child.configuration) {
79+
is RootConfig.Settings -> stackAnimator(tween()) { factor, _, content ->
80+
content(
81+
Modifier.layout { measurable, constraints ->
82+
val placeable = measurable.measure(constraints)
83+
84+
layout(placeable.width, placeable.height) {
85+
placeable.placeRelative(y = -(placeable.height.toFloat() * factor).toInt(), x = 0)
86+
}
87+
}
88+
)
89+
}
90+
is RootConfig.Home -> {
91+
val current = stack.value.active
92+
93+
when (current.configuration) {
94+
is RootConfig.Settings -> stackAnimator(tween()) { factor, _, content ->
95+
content(
96+
Modifier.layout { measurable, constraints ->
97+
val placeable = measurable.measure(constraints)
98+
99+
layout(placeable.width, placeable.height) {
100+
placeable.placeRelative(y = -(placeable.height.toFloat() * factor).toInt(), x = 0)
101+
}
102+
}
103+
)
104+
}
105+
else -> slide()
106+
}
107+
}
108+
else -> slide()
109+
}
110+
},
65111
onBack = {
66112
navigation.pop()
67113
}

composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/RootConfig.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,7 @@ sealed class RootConfig {
1313
data class Details(val medium: Medium) : RootConfig() {
1414
constructor(id: Int) : this(Medium(id))
1515
}
16+
17+
@Serializable
18+
data object Settings : RootConfig()
1619
}

composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/initial/InitialComponent.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ interface InitialComponent : Component {
1818
val pages: Value<ChildPages<View, Component>>
1919

2020
fun selectPage(index: Int)
21+
fun viewProfile()
2122
fun viewAnime()
2223
fun viewManga()
2324

composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/initial/InitialScreenComponent.kt

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,29 +16,27 @@ import dev.datlag.aniflow.anilist.model.Medium
1616
import dev.datlag.aniflow.anilist.type.MediaType
1717
import dev.datlag.aniflow.common.onRender
1818
import dev.datlag.aniflow.model.coroutines.Executor
19+
import dev.datlag.aniflow.other.StateSaver
1920
import dev.datlag.aniflow.settings.Settings
2021
import dev.datlag.aniflow.ui.navigation.Component
2122
import dev.datlag.aniflow.ui.navigation.ContentHolderComponent
2223
import dev.datlag.aniflow.ui.navigation.screen.initial.favorites.FavoritesScreenComponent
2324
import dev.datlag.aniflow.ui.navigation.screen.initial.home.HomeScreenComponent
24-
import dev.datlag.aniflow.ui.navigation.screen.initial.settings.SettingsScreenComponent
25+
import dev.datlag.aniflow.ui.navigation.screen.settings.SettingsScreenComponent
2526
import kotlinx.coroutines.flow.map
2627
import org.kodein.di.DI
2728
import org.kodein.di.instance
2829

2930
class InitialScreenComponent(
3031
componentContext: ComponentContext,
3132
override val di: DI,
32-
private val onMediumDetails: (Medium) -> Unit
33+
private val onMediumDetails: (Medium) -> Unit,
34+
private val onProfile: () -> Unit
3335
) : InitialComponent, ComponentContext by componentContext {
3436

3537
private val appSettings by di.instance<Settings.PlatformAppSettings>()
3638

3739
override val pagerItems: List<InitialComponent.PagerItem> = listOf(
38-
InitialComponent.PagerItem(
39-
label = SharedRes.strings.profile,
40-
icon = Icons.Filled.AccountCircle
41-
),
4240
InitialComponent.PagerItem(
4341
label = SharedRes.strings.home,
4442
icon = Icons.Default.Home
@@ -59,11 +57,10 @@ class InitialScreenComponent(
5957
initialPages = {
6058
Pages(
6159
items = listOf(
62-
View.Settings,
6360
View.Home,
6461
View.Favorites
6562
),
66-
selectedIndex = 1
63+
selectedIndex = 0
6764
)
6865
},
6966
childFactory = ::createChild
@@ -99,10 +96,6 @@ class InitialScreenComponent(
9996
di = di,
10097
onMediumDetails = onMediumDetails
10198
)
102-
is View.Settings -> SettingsScreenComponent(
103-
componentContext = componentContext,
104-
di = di
105-
)
10699
is View.Favorites -> FavoritesScreenComponent(
107100
componentContext = componentContext,
108101
di = di
@@ -119,7 +112,12 @@ class InitialScreenComponent(
119112
}
120113
}
121114

115+
override fun viewProfile() {
116+
onProfile()
117+
}
118+
122119
override fun viewAnime() {
120+
StateSaver.Home.updateAllLoading()
123121
launchIO {
124122
viewTypeExecutor.enqueue {
125123
appSettings.setViewManga(false)
@@ -128,6 +126,7 @@ class InitialScreenComponent(
128126
}
129127

130128
override fun viewManga() {
129+
StateSaver.Home.updateAllLoading()
131130
launchIO {
132131
viewTypeExecutor.enqueue {
133132
appSettings.setViewManga(true)

composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/initial/View.kt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ sealed class View {
77
@Serializable
88
data object Home : View()
99

10-
@Serializable
11-
data object Settings : View()
12-
1310
@Serializable
1411
data object Favorites : View()
1512
}

composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/initial/component/CompactScreen.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ fun CompactScreen(component: InitialComponent) {
4646
scrollBehavior = scrollBehavior,
4747
viewTypeFlow = component.viewing,
4848
onProfileClick = {
49-
49+
component.viewProfile()
5050
},
5151
onAnimeClick = {
5252
component.viewAnime()

composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/initial/component/ExpandedScreen.kt

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,44 @@ import androidx.compose.material3.*
88
import androidx.compose.runtime.Composable
99
import androidx.compose.runtime.getValue
1010
import androidx.compose.ui.Modifier
11+
import androidx.compose.ui.input.nestedscroll.nestedScroll
1112
import androidx.compose.ui.unit.dp
1213
import com.arkivanov.decompose.ExperimentalDecomposeApi
1314
import com.arkivanov.decompose.extensions.compose.subscribeAsState
1415
import dev.datlag.aniflow.common.isScrollingUp
1516
import dev.datlag.aniflow.ui.custom.ExpandedPages
1617
import dev.datlag.aniflow.ui.navigation.screen.initial.InitialComponent
18+
import dev.datlag.aniflow.ui.navigation.screen.initial.home.component.CollapsingToolbar
1719
import dev.datlag.aniflow.ui.navigation.screen.initial.model.FABConfig
1820
import dev.datlag.tooling.compose.EndCornerShape
1921
import dev.icerock.moko.resources.compose.stringResource
2022

21-
@OptIn(ExperimentalDecomposeApi::class)
23+
@OptIn(ExperimentalDecomposeApi::class, ExperimentalMaterial3Api::class)
2224
@Composable
2325
fun ExpandedScreen(component: InitialComponent) {
26+
val appBarState = rememberTopAppBarState()
27+
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(
28+
state = appBarState
29+
)
30+
2431
Scaffold(
32+
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
33+
topBar = {
34+
CollapsingToolbar(
35+
state = appBarState,
36+
scrollBehavior = scrollBehavior,
37+
viewTypeFlow = component.viewing,
38+
onProfileClick = {
39+
component.viewProfile()
40+
},
41+
onAnimeClick = {
42+
component.viewAnime()
43+
},
44+
onMangaClick = {
45+
component.viewManga()
46+
}
47+
)
48+
},
2549
floatingActionButton = {
2650
val state by FABConfig.state
2751

composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/initial/component/MediumScreen.kt

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,42 @@ import androidx.compose.material3.*
99
import androidx.compose.runtime.Composable
1010
import androidx.compose.runtime.getValue
1111
import androidx.compose.ui.Modifier
12+
import androidx.compose.ui.input.nestedscroll.nestedScroll
1213
import com.arkivanov.decompose.ExperimentalDecomposeApi
1314
import com.arkivanov.decompose.extensions.compose.subscribeAsState
1415
import dev.datlag.aniflow.common.isScrollingUp
1516
import dev.datlag.aniflow.ui.custom.ExpandedPages
1617
import dev.datlag.aniflow.ui.navigation.screen.initial.InitialComponent
18+
import dev.datlag.aniflow.ui.navigation.screen.initial.home.component.CollapsingToolbar
1719
import dev.datlag.aniflow.ui.navigation.screen.initial.model.FABConfig
1820
import dev.icerock.moko.resources.compose.stringResource
1921

20-
@OptIn(ExperimentalDecomposeApi::class)
22+
@OptIn(ExperimentalDecomposeApi::class, ExperimentalMaterial3Api::class)
2123
@Composable
2224
fun MediumScreen(component: InitialComponent) {
25+
val appBarState = rememberTopAppBarState()
26+
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(
27+
state = appBarState
28+
)
29+
2330
Scaffold(
31+
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
32+
topBar = {
33+
CollapsingToolbar(
34+
state = appBarState,
35+
scrollBehavior = scrollBehavior,
36+
viewTypeFlow = component.viewing,
37+
onProfileClick = {
38+
component.viewProfile()
39+
},
40+
onAnimeClick = {
41+
component.viewAnime()
42+
},
43+
onMangaClick = {
44+
component.viewManga()
45+
}
46+
)
47+
},
2448
floatingActionButton = {
2549
val state by FABConfig.state
2650

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package dev.datlag.aniflow.ui.navigation.screen.initial.settings
1+
package dev.datlag.aniflow.ui.navigation.screen.settings
22

33
import dev.datlag.aniflow.anilist.model.User
44
import dev.datlag.aniflow.ui.navigation.Component
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package dev.datlag.aniflow.ui.navigation.screen.initial.settings
1+
package dev.datlag.aniflow.ui.navigation.screen.settings
22

33
import androidx.compose.foundation.Image
44
import androidx.compose.foundation.layout.*
@@ -23,7 +23,7 @@ import dev.datlag.aniflow.SharedRes
2323
import dev.datlag.aniflow.common.plus
2424
import dev.datlag.aniflow.other.Constants
2525
import dev.datlag.aniflow.other.StateSaver
26-
import dev.datlag.aniflow.ui.navigation.screen.initial.settings.component.*
26+
import dev.datlag.aniflow.ui.navigation.screen.settings.component.*
2727
import dev.datlag.tooling.compose.onClick
2828
import dev.datlag.tooling.decompose.lifecycle.collectAsStateWithLifecycle
2929
import dev.icerock.moko.resources.compose.painterResource
@@ -38,7 +38,7 @@ fun SettingsScreen(component: SettingsComponent) {
3838

3939
LazyColumn(
4040
state = listState,
41-
modifier = Modifier.fillMaxWidth().haze(state = LocalHaze.current),
41+
modifier = Modifier.fillMaxWidth(),
4242
contentPadding = LocalPaddingValues.current?.plus(padding) ?: padding,
4343
verticalArrangement = Arrangement.spacedBy(8.dp)
4444
) {
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package dev.datlag.aniflow.ui.navigation.screen.initial.settings
1+
package dev.datlag.aniflow.ui.navigation.screen.settings
22

33
import androidx.compose.runtime.Composable
44
import com.arkivanov.decompose.ComponentContext
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package dev.datlag.aniflow.ui.navigation.screen.initial.settings.component
1+
package dev.datlag.aniflow.ui.navigation.screen.settings.component
22

33
import androidx.compose.foundation.layout.Arrangement
44
import androidx.compose.foundation.layout.Row

0 commit comments

Comments
 (0)