perf: throttle action
Some checks are pending
Build-Apk / build (push) Waiting to run

This commit is contained in:
lisonge 2024-08-01 22:16:46 +08:00
parent a60ecdf3e8
commit 8adbf711ca
21 changed files with 118 additions and 86 deletions

View File

@ -26,6 +26,7 @@ import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootNavGraph
import li.songe.gkd.BuildConfig
import li.songe.gkd.channel
import li.songe.gkd.ui.style.EmptyHeight
import li.songe.gkd.ui.style.itemPadding
import li.songe.gkd.util.GIT_COMMIT_URL
import li.songe.gkd.util.LocalNavController
@ -167,7 +168,7 @@ fun AboutPage() {
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
}
Spacer(modifier = Modifier.height(40.dp))
Spacer(modifier = Modifier.height(EmptyHeight))
}
}
}

View File

@ -84,10 +84,12 @@ import li.songe.gkd.util.appInfoCacheFlow
import li.songe.gkd.util.json
import li.songe.gkd.util.launchAsFn
import li.songe.gkd.util.launchTry
import li.songe.gkd.util.navigate
import com.ramcosta.composedestinations.navigation.navigate
import li.songe.gkd.ui.style.EmptyHeight
import li.songe.gkd.util.openApp
import li.songe.gkd.util.openUri
import li.songe.gkd.util.storeFlow
import li.songe.gkd.util.throttle
import li.songe.gkd.util.toast
import rikka.shizuku.Shizuku
@ -368,7 +370,7 @@ fun AdvancedPage() {
)
})
Spacer(modifier = Modifier.height(40.dp))
Spacer(modifier = Modifier.height(EmptyHeight))
}
}

View File

@ -71,7 +71,9 @@ import li.songe.gkd.util.ResolvedGroup
import li.songe.gkd.util.RuleSortOption
import li.songe.gkd.util.appInfoCacheFlow
import li.songe.gkd.util.launchTry
import li.songe.gkd.util.navigate
import com.ramcosta.composedestinations.navigation.navigate
import li.songe.gkd.ui.style.EmptyHeight
import li.songe.gkd.util.throttle
@RootNavGraph
@Destination(style = ProfileTransitions::class)
@ -161,7 +163,7 @@ fun AppConfigPage(appId: String) {
},
floatingActionButton = {
FloatingActionButton(
onClick = {
onClick = throttle {
navController.navigate(AppItemPageDestination(LOCAL_SUBS_ID, appId))
},
content = {
@ -187,7 +189,7 @@ fun AppConfigPage(appId: String) {
vm = vm,
group = g.group,
checked = checked,
onClick = {
onClick = throttle {
navController.navigate(
GlobalRulePageDestination(
g.subsItem.id,
@ -252,7 +254,7 @@ fun AppConfigPage(appId: String) {
}
}
item {
Spacer(modifier = Modifier.height(40.dp))
Spacer(modifier = Modifier.height(EmptyHeight))
if (globalGroups.size + appGroups.size == 0) {
Text(
text = "暂无规则",
@ -261,7 +263,7 @@ fun AppConfigPage(appId: String) {
)
} else {
// 避免被 floatingActionButton 遮挡
Spacer(modifier = Modifier.height(40.dp))
Spacer(modifier = Modifier.height(EmptyHeight))
}
}
}

View File

@ -80,7 +80,9 @@ import li.songe.gkd.util.json
import li.songe.gkd.util.json5ToJson
import li.songe.gkd.util.launchAsFn
import li.songe.gkd.util.launchTry
import li.songe.gkd.util.navigate
import com.ramcosta.composedestinations.navigation.navigate
import li.songe.gkd.ui.style.EmptyHeight
import li.songe.gkd.util.throttle
import li.songe.gkd.util.toast
import li.songe.gkd.util.updateSubscription
@ -327,7 +329,7 @@ fun AppItemPage(
}
item {
Spacer(modifier = Modifier.height(40.dp))
Spacer(modifier = Modifier.height(EmptyHeight))
if (appRaw.groups.isEmpty()) {
Text(
text = "暂无规则",
@ -335,7 +337,7 @@ fun AppItemPage(
textAlign = TextAlign.Center
)
} else if (editable) {
Spacer(modifier = Modifier.height(40.dp))
Spacer(modifier = Modifier.height(EmptyHeight))
}
}
}
@ -357,7 +359,7 @@ fun AppItemPage(
},
confirmButton = {
if (showGroupItemVal.allExampleUrls.isNotEmpty()) {
TextButton(onClick = {
TextButton(onClick = throttle {
setShowGroupItem(null)
navController.navigate(
GroupImagePageDestination(

View File

@ -51,6 +51,7 @@ import li.songe.gkd.data.RawSubscription
import li.songe.gkd.db.DbSet
import li.songe.gkd.ui.component.TowLineText
import li.songe.gkd.ui.component.getDialogResult
import li.songe.gkd.ui.style.EmptyHeight
import li.songe.gkd.ui.style.itemPadding
import li.songe.gkd.util.EnableGroupOption
import li.songe.gkd.util.LocalNavController
@ -226,7 +227,7 @@ fun CategoryPage(subsItemId: Long) {
}
}
item {
Spacer(modifier = Modifier.height(40.dp))
Spacer(modifier = Modifier.height(EmptyHeight))
if (categories.isEmpty()) {
Text(
text = "暂无类别",
@ -234,7 +235,7 @@ fun CategoryPage(subsItemId: Long) {
modifier = Modifier.fillMaxWidth()
)
} else if (editable) {
Spacer(modifier = Modifier.height(40.dp))
Spacer(modifier = Modifier.height(EmptyHeight))
}
}
}

View File

@ -64,8 +64,10 @@ import li.songe.gkd.util.LocalNavController
import li.songe.gkd.util.ProfileTransitions
import li.songe.gkd.util.appInfoCacheFlow
import li.songe.gkd.util.launchAsFn
import li.songe.gkd.util.navigate
import com.ramcosta.composedestinations.navigation.navigate
import li.songe.gkd.ui.style.EmptyHeight
import li.songe.gkd.util.subsIdToRawFlow
import li.songe.gkd.util.throttle
import li.songe.gkd.util.toast
@RootNavGraph
@ -182,7 +184,7 @@ fun ClickLogPage() {
HorizontalDivider()
}
item {
Spacer(modifier = Modifier.height(40.dp))
Spacer(modifier = Modifier.height(EmptyHeight))
if (clickLogCount == 0) {
Text(
text = "暂无记录",
@ -209,8 +211,8 @@ fun ClickLogPage() {
val appInfo = appInfoCache[clickLog.appId]
Text(text = "查看规则组", modifier = Modifier
.clickable {
clickLog.appId ?: return@clickable
.clickable(onClick = throttle {
clickLog.appId ?: return@throttle
if (clickLog.groupType == SubsConfig.AppGroupType) {
navController.navigate(
AppItemPageDestination(
@ -225,7 +227,7 @@ fun ClickLogPage() {
)
}
previewClickLog = null
}
})
.fillMaxWidth()
.padding(16.dp))
if (clickLog.groupType == SubsConfig.GlobalGroupType && clickLog.appId != null) {

View File

@ -70,6 +70,7 @@ import li.songe.gkd.db.DbSet
import li.songe.gkd.service.launcherAppId
import li.songe.gkd.ui.component.AppBarTextField
import li.songe.gkd.ui.component.TowLineText
import li.songe.gkd.ui.style.EmptyHeight
import li.songe.gkd.ui.style.appItemPadding
import li.songe.gkd.ui.style.menuPadding
import li.songe.gkd.util.LocalNavController
@ -344,14 +345,14 @@ fun GlobalRuleExcludePage(subsItemId: Long, groupKey: Int) {
}
}
item {
Spacer(modifier = Modifier.height(40.dp))
Spacer(modifier = Modifier.height(EmptyHeight))
if (showAppInfos.isEmpty()) {
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(text = "暂无搜索结果")
Spacer(modifier = Modifier.height(40.dp))
Spacer(modifier = Modifier.height(EmptyHeight))
}
}
}

View File

@ -74,7 +74,9 @@ import li.songe.gkd.util.encodeToJson5String
import li.songe.gkd.util.json
import li.songe.gkd.util.launchAsFn
import li.songe.gkd.util.launchTry
import li.songe.gkd.util.navigate
import com.ramcosta.composedestinations.navigation.navigate
import li.songe.gkd.ui.style.EmptyHeight
import li.songe.gkd.util.throttle
import li.songe.gkd.util.toast
import li.songe.gkd.util.updateSubscription
@ -233,7 +235,7 @@ fun GlobalRulePage(subsItemId: Long, focusGroupKey: Int? = null) {
text = {
Text(text = "编辑禁用")
},
onClick = {
onClick = throttle {
expanded = false
navController.navigate(
GlobalRuleExcludePageDestination(
@ -295,7 +297,7 @@ fun GlobalRulePage(subsItemId: Long, focusGroupKey: Int? = null) {
}
}
item {
Spacer(modifier = Modifier.height(40.dp))
Spacer(modifier = Modifier.height(EmptyHeight))
if (globalGroups.isEmpty()) {
Text(
text = "暂无规则",
@ -303,7 +305,7 @@ fun GlobalRulePage(subsItemId: Long, focusGroupKey: Int? = null) {
textAlign = TextAlign.Center
)
} else if (editable) {
Spacer(modifier = Modifier.height(40.dp))
Spacer(modifier = Modifier.height(EmptyHeight))
}
}
}
@ -465,7 +467,7 @@ fun GlobalRulePage(subsItemId: Long, focusGroupKey: Int? = null) {
},
confirmButton = {
if (showGroupItem.allExampleUrls.isNotEmpty()) {
TextButton(onClick = {
TextButton(onClick = throttle {
setShowGroupItem(null)
navController.navigate(
GroupImagePageDestination(

View File

@ -43,8 +43,10 @@ import li.songe.gkd.ui.style.itemPadding
import li.songe.gkd.util.LocalNavController
import li.songe.gkd.util.ProfileTransitions
import li.songe.gkd.util.appInfoCacheFlow
import li.songe.gkd.util.navigate
import com.ramcosta.composedestinations.navigation.navigate
import li.songe.gkd.ui.style.EmptyHeight
import li.songe.gkd.util.ruleSummaryFlow
import li.songe.gkd.util.throttle
@RootNavGraph
@Destination(style = ProfileTransitions::class)
@ -91,14 +93,14 @@ fun SlowGroupPage() {
) { (group, rule) ->
SlowGroupCard(
modifier = Modifier
.clickable {
.clickable(onClick = throttle {
navController.navigate(
GlobalRulePageDestination(
rule.subsItem.id,
group.key
)
)
}
})
.itemPadding(),
title = group.name,
desc = "${rule.rawSubs.name}/全局规则"
@ -110,7 +112,7 @@ fun SlowGroupPage() {
) { (group, rule) ->
SlowGroupCard(
modifier = Modifier
.clickable {
.clickable(onClick = throttle {
navController.navigate(
AppItemPageDestination(
rule.subsItem.id,
@ -118,14 +120,14 @@ fun SlowGroupPage() {
group.key
)
)
}
})
.itemPadding(),
title = group.name,
desc = "${rule.rawSubs.name}/应用规则/${appInfoCache[rule.app.id]?.name ?: rule.app.name ?: rule.app.id}"
)
}
item {
Spacer(modifier = Modifier.height(40.dp))
Spacer(modifier = Modifier.height(EmptyHeight))
if (ruleSummary.slowGroupCount == 0) {
Text(
text = "暂无规则",

View File

@ -65,9 +65,11 @@ import li.songe.gkd.util.LocalNavController
import li.songe.gkd.util.LocalPickContentLauncher
import li.songe.gkd.util.ProfileTransitions
import li.songe.gkd.util.launchAsFn
import li.songe.gkd.util.navigate
import com.ramcosta.composedestinations.navigation.navigate
import li.songe.gkd.ui.style.EmptyHeight
import li.songe.gkd.util.shareFile
import li.songe.gkd.util.snapshotZipDir
import li.songe.gkd.util.throttle
import li.songe.gkd.util.toast
@RootNavGraph
@ -156,7 +158,7 @@ fun SnapshotPage() {
HorizontalDivider()
}
item {
Spacer(modifier = Modifier.height(40.dp))
Spacer(modifier = Modifier.height(EmptyHeight))
if (snapshots.isEmpty()) {
Text(
text = "暂无记录",
@ -182,7 +184,7 @@ fun SnapshotPage() {
.padding(16.dp)
Text(
text = "查看", modifier = Modifier
.clickable(onClick = scope.launchAsFn {
.clickable(onClick = throttle(fn = scope.launchAsFn {
navController.navigate(
ImagePreviewPageDestination(
filePath = snapshotVal.screenshotFile.absolutePath,
@ -190,7 +192,7 @@ fun SnapshotPage() {
)
)
selectedSnapshot = null
})
}))
.then(modifier)
)
HorizontalDivider()

View File

@ -45,12 +45,12 @@ import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.viewModelScope
import com.blankj.utilcode.util.LogUtils
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootNavGraph
import com.ramcosta.composedestinations.navigation.navigate
import li.songe.gkd.data.RawSubscription
import li.songe.gkd.data.SubsConfig
import li.songe.gkd.db.DbSet
@ -59,6 +59,7 @@ import li.songe.gkd.ui.component.SubsAppCard
import li.songe.gkd.ui.component.TowLineText
import li.songe.gkd.ui.component.getDialogResult
import li.songe.gkd.ui.destinations.AppItemPageDestination
import li.songe.gkd.ui.style.EmptyHeight
import li.songe.gkd.ui.style.menuPadding
import li.songe.gkd.util.LocalNavController
import li.songe.gkd.util.ProfileTransitions
@ -68,7 +69,7 @@ import li.songe.gkd.util.encodeToJson5String
import li.songe.gkd.util.json
import li.songe.gkd.util.launchAsFn
import li.songe.gkd.util.launchTry
import li.songe.gkd.util.navigate
import li.songe.gkd.util.throttle
import li.songe.gkd.util.toast
import li.songe.gkd.util.updateSubscription
@ -249,10 +250,10 @@ fun SubsPage(
appInfo = appInfoCache[appRaw.id],
subsConfig = subsConfig,
enableSize = enableSize,
onClick = {
onClick = throttle {
navController.navigate(AppItemPageDestination(subsItemId, appRaw.id))
},
onValueChange = scope.launchAsFn { enable ->
onValueChange = throttle(fn = scope.launchAsFn { enable ->
val newItem = subsConfig?.copy(
enable = enable
) ?: SubsConfig(
@ -262,9 +263,9 @@ fun SubsPage(
appId = appRaw.id,
)
DbSet.subsConfigDao.insert(newItem)
},
}),
showMenu = editable,
onDelClick = vm.viewModelScope.launchAsFn {
onDelClick = throttle(fn = vm.viewModelScope.launchAsFn {
val result = getDialogResult(
"删除规则组",
"确定删除 ${appInfoCache[appRaw.id]?.name ?: appRaw.name ?: appRaw.id} 下所有规则组?"
@ -277,9 +278,10 @@ fun SubsPage(
toast("删除成功")
}
})
)
}
item {
Spacer(modifier = Modifier.height(40.dp))
Spacer(modifier = Modifier.height(EmptyHeight))
if (appAndConfigs.isEmpty()) {
Text(
text = if (searchStr.isNotEmpty()) "暂无搜索结果" else "暂无规则",
@ -287,7 +289,7 @@ fun SubsPage(
textAlign = TextAlign.Center
)
} else if (editable) {
Spacer(modifier = Modifier.height(40.dp))
Spacer(modifier = Modifier.height(EmptyHeight))
}
}
}

View File

@ -12,6 +12,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import li.songe.gkd.ui.style.itemPadding
import li.songe.gkd.util.throttle
@Composable
fun AuthCard(
@ -36,7 +37,7 @@ fun AuthCard(
)
}
Spacer(modifier = Modifier.width(10.dp))
OutlinedButton(onClick = onAuthClick) {
OutlinedButton(onClick = throttle(fn = onAuthClick)) {
Text(text = "授权")
}
}

View File

@ -14,6 +14,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import li.songe.gkd.ui.style.itemPadding
import li.songe.gkd.util.throttle
@Composable
fun SettingItem(
@ -24,7 +25,7 @@ fun SettingItem(
Row(
modifier = Modifier
.clickable(
onClick = onClick
onClick = throttle(fn = onClick)
)
.fillMaxWidth()
.itemPadding(),

View File

@ -187,8 +187,8 @@ fun SubsAppCard(
}
Switch(
subsConfig?.enable ?: (appInfo != null),
onValueChange,
checked = subsConfig?.enable ?: (appInfo != null),
onCheckedChange = onValueChange,
)
}
}

View File

@ -45,11 +45,12 @@ import li.songe.gkd.util.LocalNavController
import li.songe.gkd.util.formatTimeAgo
import li.songe.gkd.util.launchTry
import li.songe.gkd.util.map
import li.songe.gkd.util.navigate
import com.ramcosta.composedestinations.navigation.navigate
import li.songe.gkd.util.openUri
import li.songe.gkd.util.subsLoadErrorsFlow
import li.songe.gkd.util.subsRefreshErrorsFlow
import li.songe.gkd.util.subsRefreshingFlow
import li.songe.gkd.util.throttle
import li.songe.gkd.util.toast
@ -206,7 +207,7 @@ private fun SubsMenuItem(
text = {
Text(text = "应用规则")
},
onClick = {
onClick = throttle {
onExpandedChange(false)
navController.navigate(SubsPageDestination(subItem.id))
}
@ -217,7 +218,7 @@ private fun SubsMenuItem(
text = {
Text(text = "规则类别")
},
onClick = {
onClick = throttle {
onExpandedChange(false)
navController.navigate(CategoryPageDestination(subItem.id))
}
@ -228,7 +229,7 @@ private fun SubsMenuItem(
text = {
Text(text = "全局规则")
},
onClick = {
onClick = throttle {
onExpandedChange(false)
navController.navigate(GlobalRulePageDestination(subItem.id))
}

View File

@ -12,6 +12,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import li.songe.gkd.ui.style.itemPadding
import li.songe.gkd.util.throttle
@Composable
fun TextSwitch(
@ -48,7 +49,7 @@ fun TextSwitch(
Switch(
checked = checked,
enabled = enabled,
onCheckedChange = onCheckedChange,
onCheckedChange = onCheckedChange?.let { throttle(fn = it) },
)
}
}

View File

@ -74,9 +74,11 @@ import li.songe.gkd.util.LocalNavController
import li.songe.gkd.util.SortTypeOption
import li.songe.gkd.util.appRefreshingFlow
import li.songe.gkd.util.launchAsFn
import li.songe.gkd.util.navigate
import com.ramcosta.composedestinations.navigation.navigate
import li.songe.gkd.ui.style.EmptyHeight
import li.songe.gkd.util.ruleSummaryFlow
import li.songe.gkd.util.storeFlow
import li.songe.gkd.util.throttle
val appListNav = BottomNavItem(
label = "应用", icon = Icons.Default.Apps
@ -288,9 +290,9 @@ fun useAppListPage(): ScaffoldExt {
items(orderedAppInfos, { it.id }) { appInfo ->
Row(
modifier = Modifier
.clickable {
.clickable(onClick = throttle {
navController.navigate(AppConfigPageDestination(appInfo.id))
}
})
.height(IntrinsicSize.Min)
.appItemPadding(),
horizontalArrangement = Arrangement.SpaceBetween,
@ -388,7 +390,7 @@ fun useAppListPage(): ScaffoldExt {
}
}
item {
Spacer(modifier = Modifier.height(40.dp))
Spacer(modifier = Modifier.height(EmptyHeight))
if (orderedAppInfos.isEmpty() && searchStr.isNotEmpty()) {
Text(
text = "暂无搜索结果",
@ -405,7 +407,7 @@ fun useAppListPage(): ScaffoldExt {
.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally
) {
Spacer(modifier = Modifier.height(40.dp))
Spacer(modifier = Modifier.height(EmptyHeight))
CircularProgressIndicator()
}
}

View File

@ -31,9 +31,9 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.viewModelScope
import com.ramcosta.composedestinations.navigation.navigate
import li.songe.gkd.MainActivity
import li.songe.gkd.permission.checkOrRequestPermission
import li.songe.gkd.permission.notificationState
@ -43,14 +43,15 @@ import li.songe.gkd.ui.component.AuthCard
import li.songe.gkd.ui.component.TextSwitch
import li.songe.gkd.ui.destinations.ClickLogPageDestination
import li.songe.gkd.ui.destinations.SlowGroupPageDestination
import li.songe.gkd.ui.style.EmptyHeight
import li.songe.gkd.ui.style.itemPadding
import li.songe.gkd.util.HOME_PAGE_URL
import li.songe.gkd.util.LocalNavController
import li.songe.gkd.util.launchAsFn
import li.songe.gkd.util.navigate
import li.songe.gkd.util.openUri
import li.songe.gkd.util.ruleSummaryFlow
import li.songe.gkd.util.storeFlow
import li.songe.gkd.util.throttle
import li.songe.gkd.util.tryStartActivity
val controlNav = BottomNavItem(label = "主页", icon = Icons.Outlined.Home)
@ -77,7 +78,7 @@ fun useControlPage(): ScaffoldExt {
text = controlNav.label,
)
}, actions = {
IconButton(onClick = { context.openUri(HOME_PAGE_URL) }) {
IconButton(onClick = throttle { context.openUri(HOME_PAGE_URL) }) {
Icon(
imageVector = Icons.AutoMirrored.Outlined.HelpOutline,
contentDescription = null,
@ -138,9 +139,9 @@ fun useControlPage(): ScaffoldExt {
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.clickable {
.clickable(onClick = throttle {
navController.navigate(ClickLogPageDestination)
}
})
.itemPadding(),
) {
Column(modifier = Modifier.weight(1f)) {
@ -165,9 +166,9 @@ fun useControlPage(): ScaffoldExt {
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.clickable {
.clickable(onClick = throttle {
navController.navigate(SlowGroupPageDestination)
}
})
.itemPadding(),
) {
Column(modifier = Modifier.weight(1f)) {
@ -209,7 +210,7 @@ fun useControlPage(): ScaffoldExt {
}
}
Spacer(modifier = Modifier.height(40.dp))
Spacer(modifier = Modifier.height(EmptyHeight))
}
}
}

View File

@ -7,6 +7,7 @@ import androidx.compose.ui.unit.dp
val itemHorizontalPadding = 16.dp
val itemVerticalPadding = 12.dp
val EmptyHeight = 40.dp
fun Modifier.itemPadding() = this then padding(itemHorizontalPadding, itemVerticalPadding)

View File

@ -1,21 +1,8 @@
package li.songe.gkd.util
import androidx.compose.runtime.compositionLocalOf
import androidx.navigation.NavController
import androidx.navigation.NavHostController
import androidx.navigation.NavOptionsBuilder
import com.ramcosta.composedestinations.spec.Direction
val LocalNavController =
compositionLocalOf<NavHostController> { error("not found DestinationsNavigator") }
private val navThrottle = useThrottle()
fun NavController.navigate(
direction: Direction,
navOptionsBuilder: NavOptionsBuilder.() -> Unit = {},
) {
navThrottle {
navigate(direction.route, navOptionsBuilder)
}
}

View File

@ -36,13 +36,31 @@ fun Long.format(formatStr: String): String {
return df.format(this)
}
fun useThrottle(interval: Long = 500L): (fn: () -> Unit) -> Unit {
var lastTriggerTime = 0L
return { fn ->
private var globalThrottleLastTriggerTime = 0L
private const val defaultThrottleInterval = 1000L
fun throttle(
interval: Long = defaultThrottleInterval,
fn: (() -> Unit)?,
): (() -> Unit) {
return {
val t = System.currentTimeMillis()
if (t - lastTriggerTime > interval) {
lastTriggerTime = t
fn()
if (t - globalThrottleLastTriggerTime > interval) {
globalThrottleLastTriggerTime = t
fn?.invoke()
}
}
}
}
fun <T> throttle(
interval: Long = defaultThrottleInterval,
fn: ((T) -> Unit)?,
): ((T) -> Unit) {
return {
val t = System.currentTimeMillis()
if (t - globalThrottleLastTriggerTime > interval) {
globalThrottleLastTriggerTime = t
fn?.invoke(it)
}
}
}