Skip to content

Commit cf64b5e

Browse files
committed
增加公共emitter,处理双击tab事件
1 parent a5c331e commit cf64b5e

15 files changed

+232
-140
lines changed

bilimiao-compose/src/main/java/cn/a10miaomiao/bilimiao/compose/ComposeFragment.kt

+11-6
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ import androidx.navigation.compose.rememberNavController
2828
import androidx.navigation.fragment.FragmentNavigatorDestinationBuilder
2929
import androidx.navigation.fragment.findNavController
3030
import cn.a10miaomiao.bilimiao.compose.common.LocalContainerView
31+
import cn.a10miaomiao.bilimiao.compose.common.LocalEmitter
32+
import cn.a10miaomiao.bilimiao.compose.common.LocalPageNavigation
3133
import cn.a10miaomiao.bilimiao.compose.common.addPaddingValues
34+
import cn.a10miaomiao.bilimiao.compose.common.emitter.SharedFlowEmitter
3235
import cn.a10miaomiao.bilimiao.compose.common.localContainerView
3336
import cn.a10miaomiao.bilimiao.compose.common.mypage.LocalPageConfigInfo
3437
import cn.a10miaomiao.bilimiao.compose.common.mypage.PageConfigInfo
@@ -109,15 +112,15 @@ class ComposeFragment : Fragment(), MyPage, DIAware, OnBackPressedDispatcherOwne
109112
bindSingleton { this@ComposeFragment }
110113
bindSingleton { this@ComposeFragment.requireArguments() }
111114
bindSingleton { messageDialogState }
112-
bindSingleton {
113-
PageNavigation(
114-
this@ComposeFragment,
115-
navHostController = { composeNav },
116-
)
117-
}
115+
bindSingleton { emitter }
116+
bindSingleton { pageNavigation }
118117
}
119118

119+
private val pageNavigation = PageNavigation(
120+
this, { composeNav }
121+
)
120122
private val pageConfigInfo = PageConfigInfo(this)
123+
private val emitter = SharedFlowEmitter()
121124

122125
override val pageConfig = myPageConfig {
123126
val config = pageConfigInfo.lastConfig()
@@ -161,6 +164,8 @@ class ComposeFragment : Fragment(), MyPage, DIAware, OnBackPressedDispatcherOwne
161164
LocalContainerView provides container,
162165
LocalPageConfigInfo provides pageConfigInfo,
163166
LocalOnBackPressedDispatcherOwner provides this@ComposeFragment,
167+
LocalPageNavigation provides pageNavigation,
168+
LocalEmitter provides emitter,
164169
) {
165170
withDI(di = di) {
166171
val windowStore: WindowStore by rememberInstance()

bilimiao-compose/src/main/java/cn/a10miaomiao/bilimiao/compose/common/CompositionLocal.kt

+10-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import androidx.compose.runtime.Composable
55
import androidx.compose.runtime.staticCompositionLocalOf
66
import androidx.fragment.app.Fragment
77
import androidx.navigation.NavHostController
8+
import cn.a10miaomiao.bilimiao.compose.common.emitter.SharedFlowEmitter
9+
import cn.a10miaomiao.bilimiao.compose.common.navigation.PageNavigation
810

911

1012
private fun noLocalProvidedFor(name: String): Nothing {
@@ -18,11 +20,16 @@ internal val LocalContainerView = staticCompositionLocalOf<ViewGroup?> {
1820
@Composable
1921
fun localContainerView() = LocalContainerView.current
2022

21-
internal val LocalPageRouter = staticCompositionLocalOf<PageRouter> {
22-
noLocalProvidedFor("LocalPageRouter")
23+
internal val LocalPageNavigation = staticCompositionLocalOf<PageNavigation> {
24+
noLocalProvidedFor("PageNavigation")
2325
}
2426

2527
@Composable
26-
fun localPageRouter() = LocalPageRouter.current
28+
fun localPageNavigation() = LocalPageNavigation.current
2729

30+
internal val LocalEmitter = staticCompositionLocalOf<SharedFlowEmitter> {
31+
noLocalProvidedFor("SharedFlowEmitter")
32+
}
2833

34+
@Composable
35+
fun localEmitter() = LocalEmitter.current

bilimiao-compose/src/main/java/cn/a10miaomiao/bilimiao/compose/common/PageRouter.kt

-29
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package cn.a10miaomiao.bilimiao.compose.common.emitter
2+
3+
sealed class EmitterAction {
4+
data class DoubleClickTab(
5+
val tab: String,
6+
): EmitterAction()
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package cn.a10miaomiao.bilimiao.compose.common.emitter
2+
3+
import androidx.compose.runtime.Stable
4+
import kotlinx.coroutines.flow.FlowCollector
5+
import kotlinx.coroutines.flow.MutableSharedFlow
6+
import kotlinx.coroutines.flow.SharedFlow
7+
8+
@Stable
9+
class SharedFlowEmitter {
10+
11+
private val sharedFlow = MutableSharedFlow<EmitterAction>()
12+
val flow: SharedFlow<EmitterAction> get () = sharedFlow
13+
14+
suspend fun emit(action: EmitterAction) {
15+
sharedFlow.emit(action)
16+
}
17+
18+
suspend fun collect(collector: FlowCollector<EmitterAction>) {
19+
sharedFlow.collect(collector)
20+
}
21+
22+
suspend inline fun <reified T: EmitterAction> collectAction(collector: FlowCollector<T>) {
23+
collect {
24+
if (it is T) collector.emit(it)
25+
}
26+
}
27+
28+
}

bilimiao-compose/src/main/java/cn/a10miaomiao/bilimiao/compose/common/foundation/TabClick.kt

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import androidx.compose.foundation.pager.PagerState
44
import androidx.compose.runtime.Composable
55
import androidx.compose.runtime.remember
66
import androidx.compose.runtime.rememberCoroutineScope
7-
import cn.a10miaomiao.bilimiao.compose.pages.home.HomePageAction
87
import kotlinx.coroutines.launch
98

109
@Composable

bilimiao-compose/src/main/java/cn/a10miaomiao/bilimiao/compose/pages/dynamic/DynamicPage.kt

+19-8
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,11 @@ import androidx.navigation.NavGraph.Companion.findStartDestination
3030
import androidx.navigation.navOptions
3131
import cn.a10miaomiao.bilimiao.compose.base.ComposePage
3232
import cn.a10miaomiao.bilimiao.compose.common.diViewModel
33+
import cn.a10miaomiao.bilimiao.compose.common.emitter.EmitterAction
34+
import cn.a10miaomiao.bilimiao.compose.common.foundation.combinedTabDoubleClick
3335
import cn.a10miaomiao.bilimiao.compose.common.foundation.pagerTabIndicatorOffset
3436
import cn.a10miaomiao.bilimiao.compose.common.localContainerView
37+
import cn.a10miaomiao.bilimiao.compose.common.localEmitter
3538
import cn.a10miaomiao.bilimiao.compose.common.mypage.PageConfig
3639
import cn.a10miaomiao.bilimiao.compose.common.mypage.PageListener
3740
import cn.a10miaomiao.bilimiao.compose.common.mypage.rememberMyMenu
@@ -63,14 +66,14 @@ class DynamicPage : ComposePage() {
6366
}
6467

6568
private sealed class DynamicPageTab(
66-
val id: Int,
69+
val id: String,
6770
val name: String,
6871
) {
6972
@Composable
7073
abstract fun PageContent()
7174

7275
data object All : DynamicPageTab(
73-
id = 0,
76+
id = "dynamic.all",
7477
name = "全部"
7578
) {
7679
@Composable
@@ -80,7 +83,7 @@ private sealed class DynamicPageTab(
8083
}
8184

8285
data object Video : DynamicPageTab(
83-
id = 1,
86+
id = "dynamic.video",
8487
name = "视频"
8588
) {
8689
@Composable
@@ -155,6 +158,18 @@ private fun DynamicPageContent(
155158
val windowInsets = windowState.getContentInsets(localContainerView())
156159

157160
val pagerState = rememberPagerState(pageCount = { viewModel.tabs.size })
161+
val emitter = localEmitter()
162+
val combinedTabClick = combinedTabDoubleClick(
163+
pagerState = pagerState,
164+
onDoubleClick = {
165+
scope.launch {
166+
emitter.emit(EmitterAction.DoubleClickTab(
167+
tab = viewModel.tabs[it].id
168+
))
169+
}
170+
}
171+
)
172+
158173
Column(
159174
modifier = Modifier.fillMaxSize()
160175
) {
@@ -183,11 +198,7 @@ private fun DynamicPageContent(
183198
)
184199
},
185200
selected = pagerState.currentPage == index,
186-
onClick = {
187-
scope.launch {
188-
pagerState.animateScrollToPage(index)
189-
}
190-
},
201+
onClick = { combinedTabClick(index) },
191202
)
192203
}
193204
}

bilimiao-compose/src/main/java/cn/a10miaomiao/bilimiao/compose/pages/dynamic/content/DynamicAllListContent.kt

+18-14
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
1515
import androidx.compose.foundation.lazy.grid.items
1616
import androidx.compose.foundation.lazy.grid.rememberLazyGridState
1717
import androidx.compose.foundation.lazy.items
18+
import androidx.compose.foundation.lazy.rememberLazyListState
1819
import androidx.compose.runtime.Composable
20+
import androidx.compose.runtime.LaunchedEffect
1921
import androidx.compose.runtime.collectAsState
2022
import androidx.compose.runtime.getValue
2123
import androidx.compose.ui.Alignment
@@ -27,8 +29,10 @@ import bilibili.app.dynamic.v2.DynamicGRPC
2729
import bilibili.app.dynamic.v2.DynamicItem
2830
import cn.a10miaomiao.bilimiao.compose.common.addPaddingValues
2931
import cn.a10miaomiao.bilimiao.compose.common.diViewModel
32+
import cn.a10miaomiao.bilimiao.compose.common.emitter.EmitterAction
3033
import cn.a10miaomiao.bilimiao.compose.common.entity.FlowPaginationInfo
3134
import cn.a10miaomiao.bilimiao.compose.common.localContainerView
35+
import cn.a10miaomiao.bilimiao.compose.common.localEmitter
3236
import cn.a10miaomiao.bilimiao.compose.common.navigation.PageNavigation
3337
import cn.a10miaomiao.bilimiao.compose.common.toPaddingValues
3438
import cn.a10miaomiao.bilimiao.compose.components.dyanmic.DynamicItemCard
@@ -161,26 +165,26 @@ fun DynamicAllListContent() {
161165
val listFail by viewModel.list.fail.collectAsState()
162166
val isRefreshing by viewModel.isRefreshing.collectAsState()
163167

164-
val listState = rememberLazyGridState()
165-
// LaunchedEffect(Unit) {
166-
// action.collect {
167-
// when (it) {
168-
// is HomePageAction.DoubleClickTab -> {
169-
// if (listState.firstVisibleItemIndex == 0) {
170-
// viewModel.refresh()
171-
// } else {
172-
// listState.animateScrollToItem(0)
173-
// }
174-
// }
175-
// }
176-
// }
177-
// }
168+
val listState = rememberLazyListState()
169+
val emitter = localEmitter()
170+
LaunchedEffect(Unit) {
171+
emitter.collectAction<EmitterAction.DoubleClickTab> {
172+
if (it.tab == "dynamic.all") {
173+
if (listState.firstVisibleItemIndex == 0) {
174+
viewModel.refresh()
175+
} else {
176+
listState.animateScrollToItem(0)
177+
}
178+
}
179+
}
180+
}
178181

179182
SwipeToRefresh(
180183
refreshing = isRefreshing,
181184
onRefresh = { viewModel.refresh() },
182185
) {
183186
LazyColumn(
187+
state = listState,
184188
modifier = Modifier.fillMaxSize(),
185189
contentPadding = windowInsets.addPaddingValues(
186190
addTop = -windowInsets.topDp.dp + 10.dp,

bilimiao-compose/src/main/java/cn/a10miaomiao/bilimiao/compose/pages/dynamic/content/DynamicVideoListContent.kt

+14-14
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ import androidx.navigation.Navigation
2222
import bilibili.app.dynamic.v2.DynamicGRPC
2323
import cn.a10miaomiao.bilimiao.compose.BilimiaoPageRoute
2424
import cn.a10miaomiao.bilimiao.compose.common.diViewModel
25+
import cn.a10miaomiao.bilimiao.compose.common.emitter.EmitterAction
2526
import cn.a10miaomiao.bilimiao.compose.common.entity.FlowPaginationInfo
2627
import cn.a10miaomiao.bilimiao.compose.common.localContainerView
28+
import cn.a10miaomiao.bilimiao.compose.common.localEmitter
2729
import cn.a10miaomiao.bilimiao.compose.common.navigation.PageNavigation
2830
import cn.a10miaomiao.bilimiao.compose.common.toPaddingValues
2931
import cn.a10miaomiao.bilimiao.compose.components.dyanmic.DynamicModuleAuthorBox
@@ -35,7 +37,6 @@ import cn.a10miaomiao.bilimiao.compose.components.video.VideoItemBox
3537
import cn.a10miaomiao.bilimiao.compose.pages.bangumi.BangumiDetailPage
3638
import cn.a10miaomiao.bilimiao.compose.pages.dynamic.DynamicVideoContentInfo
3739
import cn.a10miaomiao.bilimiao.compose.pages.dynamic.DynamicVideoInfo
38-
import cn.a10miaomiao.bilimiao.compose.pages.home.HomePageAction
3940
import cn.a10miaomiao.bilimiao.compose.pages.user.UserSpacePage
4041
import com.a10miaomiao.bilimiao.comm.network.BiliGRPCHttp
4142
import com.a10miaomiao.bilimiao.comm.store.FilterStore
@@ -212,19 +213,18 @@ fun DynamicVideoListContent() {
212213
val isRefreshing by viewModel.isRefreshing.collectAsState()
213214

214215
val listState = rememberLazyGridState()
215-
// LaunchedEffect(Unit) {
216-
// action.collect {
217-
// when (it) {
218-
// is HomePageAction.DoubleClickTab -> {
219-
// if (listState.firstVisibleItemIndex == 0) {
220-
// viewModel.refresh()
221-
// } else {
222-
// listState.animateScrollToItem(0)
223-
// }
224-
// }
225-
// }
226-
// }
227-
// }
216+
val emitter = localEmitter()
217+
LaunchedEffect(Unit) {
218+
emitter.collectAction<EmitterAction.DoubleClickTab> {
219+
if (it.tab == "dynamic.video") {
220+
if (listState.firstVisibleItemIndex == 0) {
221+
viewModel.refresh()
222+
} else {
223+
listState.animateScrollToItem(0)
224+
}
225+
}
226+
}
227+
}
228228

229229
SwipeToRefresh(
230230
refreshing = isRefreshing,

0 commit comments

Comments
 (0)