State hoisting for FeedsPage

This commit is contained in:
Ash 2022-04-02 20:12:05 +08:00
parent 9bf93ebc11
commit ac5e68bf86
2 changed files with 70 additions and 73 deletions

View File

@ -30,8 +30,10 @@ fun HomePage(
readViewModel: ReadViewModel = hiltViewModel(), readViewModel: ReadViewModel = hiltViewModel(),
feedOptionViewModel: FeedOptionViewModel = hiltViewModel(), feedOptionViewModel: FeedOptionViewModel = hiltViewModel(),
) { ) {
val viewState = viewModel.viewState.collectAsStateValue()
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val viewState = viewModel.viewState.collectAsStateValue()
val filterState = viewModel.filterState.collectAsStateValue()
val syncState = viewModel.syncState.collectAsStateValue()
OpenArticleByExtras(extrasArticleId) OpenArticleByExtras(extrasArticleId)
@ -71,7 +73,25 @@ fun HomePage(
state = viewState.pagerState, state = viewState.pagerState,
composableList = listOf( composableList = listOf(
{ {
FeedsPage(navController = navController) FeedsPage(
navController = navController,
filterState = filterState,
syncState = syncState,
onSyncClick = {
viewModel.dispatch(HomeViewAction.Sync)
},
onFilterChange = {
viewModel.dispatch(HomeViewAction.ChangeFilter(it))
},
onScrollToPage = {
viewModel.dispatch(
HomeViewAction.ScrollToPage(
scope = scope,
targetPage = it,
)
)
}
)
}, },
{ {
FlowPage(navController = navController) FlowPage(navController = navController)

View File

@ -2,7 +2,6 @@ package me.ash.reader.ui.page.home.feeds
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.Crossfade
import androidx.compose.animation.core.* import androidx.compose.animation.core.*
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.gestures.detectTapGestures
@ -18,7 +17,6 @@ import androidx.compose.material3.*
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate import androidx.compose.ui.draw.rotate
import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.input.pointer.pointerInput
@ -29,12 +27,12 @@ import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import me.ash.reader.R import me.ash.reader.R
import me.ash.reader.data.repository.AbstractRssRepository
import me.ash.reader.ui.extension.collectAsStateValue import me.ash.reader.ui.extension.collectAsStateValue
import me.ash.reader.ui.extension.getDesc import me.ash.reader.ui.extension.getDesc
import me.ash.reader.ui.extension.getName import me.ash.reader.ui.extension.getName
import me.ash.reader.ui.page.home.FilterBar import me.ash.reader.ui.page.home.FilterBar
import me.ash.reader.ui.page.home.HomeViewAction import me.ash.reader.ui.page.home.FilterState
import me.ash.reader.ui.page.home.HomeViewModel
import me.ash.reader.ui.page.home.feeds.subscribe.SubscribeDialog import me.ash.reader.ui.page.home.feeds.subscribe.SubscribeDialog
import me.ash.reader.ui.page.home.feeds.subscribe.SubscribeViewAction import me.ash.reader.ui.page.home.feeds.subscribe.SubscribeViewAction
import me.ash.reader.ui.page.home.feeds.subscribe.SubscribeViewModel import me.ash.reader.ui.page.home.feeds.subscribe.SubscribeViewModel
@ -50,14 +48,15 @@ fun FeedsPage(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
navController: NavHostController, navController: NavHostController,
feedsViewModel: FeedsViewModel = hiltViewModel(), feedsViewModel: FeedsViewModel = hiltViewModel(),
homeViewModel: HomeViewModel = hiltViewModel(), filterState: FilterState,
syncState: AbstractRssRepository.SyncState,
subscribeViewModel: SubscribeViewModel = hiltViewModel(), subscribeViewModel: SubscribeViewModel = hiltViewModel(),
onSyncClick: () -> Unit = {},
onFilterChange: (filterState: FilterState) -> Unit = {},
onScrollToPage: (targetPage: Int) -> Unit = {},
) { ) {
val context = LocalContext.current val context = LocalContext.current
val scope = rememberCoroutineScope()
val viewState = feedsViewModel.viewState.collectAsStateValue() val viewState = feedsViewModel.viewState.collectAsStateValue()
val filterState = homeViewModel.filterState.collectAsStateValue()
val syncState = homeViewModel.syncState.collectAsStateValue()
val infiniteTransition = rememberInfiniteTransition() val infiniteTransition = rememberInfiniteTransition()
val angle by infiniteTransition.animateFloat( val angle by infiniteTransition.animateFloat(
@ -84,12 +83,11 @@ fun FeedsPage(
feedsViewModel.dispatch(FeedsViewAction.FetchAccount) feedsViewModel.dispatch(FeedsViewAction.FetchAccount)
} }
LaunchedEffect(homeViewModel.filterState) {
homeViewModel.filterState.collect { state -> LaunchedEffect(filterState) {
feedsViewModel.dispatch( feedsViewModel.dispatch(
FeedsViewAction.FetchData(state) FeedsViewAction.FetchData(filterState)
) )
}
} }
Scaffold( Scaffold(
@ -99,6 +97,7 @@ fun FeedsPage(
title = {}, title = {},
navigationIcon = { navigationIcon = {
IconButton(onClick = { IconButton(onClick = {
onScrollToPage(0)
}) { }) {
Icon( Icon(
imageVector = Icons.Rounded.ArrowBack, imageVector = Icons.Rounded.ArrowBack,
@ -109,8 +108,9 @@ fun FeedsPage(
}, },
actions = { actions = {
IconButton(onClick = { IconButton(onClick = {
if (syncState.isSyncing) return@IconButton if (syncState.isNotSyncing) {
homeViewModel.dispatch(HomeViewAction.Sync) onSyncClick()
}
}) { }) {
Icon( Icon(
modifier = Modifier.rotate(if (syncState.isSyncing) angle else 0f), modifier = Modifier.rotate(if (syncState.isSyncing) angle else 0f),
@ -174,20 +174,13 @@ fun FeedsPage(
) )
}, },
) { ) {
homeViewModel.dispatch( onFilterChange(
HomeViewAction.ChangeFilter( filterState.copy(
filterState.copy( group = null,
group = null, feed = null
feed = null
)
)
)
homeViewModel.dispatch(
HomeViewAction.ScrollToPage(
scope = scope,
targetPage = 1,
) )
) )
onScrollToPage(1)
} }
} }
item { item {
@ -199,49 +192,35 @@ fun FeedsPage(
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
} }
itemsIndexed(viewState.groupWithFeedList) { index, groupWithFeed -> itemsIndexed(viewState.groupWithFeedList) { index, groupWithFeed ->
Crossfade(targetState = groupWithFeed) { groupWithFeed -> // Crossfade(targetState = groupWithFeed) { groupWithFeed ->
Column { Column {
GroupItem( GroupItem(
text = groupWithFeed.group.name, text = groupWithFeed.group.name,
feeds = groupWithFeed.feeds, feeds = groupWithFeed.feeds,
groupOnClick = { groupOnClick = {
homeViewModel.dispatch( onFilterChange(
HomeViewAction.ChangeFilter( filterState.copy(
filterState.copy( group = groupWithFeed.group,
group = groupWithFeed.group, feed = null
feed = null
)
)
) )
homeViewModel.dispatch( )
HomeViewAction.ScrollToPage( onScrollToPage(1)
scope = scope, },
targetPage = 1, feedOnClick = { feed ->
) onFilterChange(
filterState.copy(
group = null,
feed = feed
) )
}, )
feedOnClick = { feed -> onScrollToPage(1)
homeViewModel.dispatch(
HomeViewAction.ChangeFilter(
filterState.copy(
group = null,
feed = feed
)
)
)
homeViewModel.dispatch(
HomeViewAction.ScrollToPage(
scope = scope,
targetPage = 1,
)
)
}
)
if (index != viewState.groupWithFeedList.lastIndex) {
Spacer(modifier = Modifier.height(8.dp))
} }
)
if (index != viewState.groupWithFeedList.lastIndex) {
Spacer(modifier = Modifier.height(8.dp))
} }
} }
// }
} }
item { item {
Spacer(modifier = Modifier.height(64.dp)) Spacer(modifier = Modifier.height(64.dp))
@ -256,11 +235,9 @@ fun FeedsPage(
.fillMaxWidth(), .fillMaxWidth(),
filter = filterState.filter, filter = filterState.filter,
filterOnClick = { filterOnClick = {
homeViewModel.dispatch( onFilterChange(
HomeViewAction.ChangeFilter( filterState.copy(
filterState.copy( filter = it
filter = it
)
) )
) )
}, },