From af97a9da323147e4c44a34373edeb5afe3e48f0c Mon Sep 17 00:00:00 2001 From: lisonge Date: Mon, 2 Sep 2024 21:17:49 +0800 Subject: [PATCH] perf: remove useless code --- .../main/kotlin/li/songe/gkd/MainActivity.kt | 105 +++++++++++------- .../gkd/composition/CompositionActivity.kt | 71 ------------ .../li/songe/gkd/composition/Typealias.kt | 3 - .../kotlin/li/songe/gkd/ui/AdvancedPage.kt | 4 +- .../kotlin/li/songe/gkd/ui/AppConfigPage.kt | 7 +- .../kotlin/li/songe/gkd/ui/AppItemPage.kt | 7 +- .../kotlin/li/songe/gkd/ui/CategoryPage.kt | 9 +- .../kotlin/li/songe/gkd/ui/GlobalRulePage.kt | 7 +- .../kotlin/li/songe/gkd/ui/SlowGroupPage.kt | 7 +- .../kotlin/li/songe/gkd/ui/SnapshotPage.kt | 5 +- .../main/kotlin/li/songe/gkd/ui/SubsPage.kt | 7 +- .../li/songe/gkd/ui/component/SubsItemCard.kt | 7 +- .../li/songe/gkd/ui/home/SettingsPage.kt | 19 ++-- .../li/songe/gkd/ui/home/SubsManagePage.kt | 11 +- .../kotlin/li/songe/gkd/util/ComposeExt.kt | 13 --- .../main/kotlin/li/songe/gkd/util/Upgrade.kt | 6 +- 16 files changed, 114 insertions(+), 174 deletions(-) delete mode 100644 app/src/main/kotlin/li/songe/gkd/composition/CompositionActivity.kt diff --git a/app/src/main/kotlin/li/songe/gkd/MainActivity.kt b/app/src/main/kotlin/li/songe/gkd/MainActivity.kt index fcd7304ee..08787986a 100644 --- a/app/src/main/kotlin/li/songe/gkd/MainActivity.kt +++ b/app/src/main/kotlin/li/songe/gkd/MainActivity.kt @@ -4,12 +4,20 @@ import android.app.Activity import android.app.ActivityManager import android.content.ComponentName import android.content.Intent +import android.graphics.Color +import android.os.Bundle +import androidx.activity.ComponentActivity import androidx.activity.compose.setContent +import androidx.activity.enableEdgeToEdge import androidx.activity.viewModels import androidx.compose.animation.core.AnimationConstants import androidx.compose.runtime.CompositionLocalProvider +import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat import androidx.lifecycle.lifecycleScope import androidx.navigation.compose.rememberNavController +import com.blankj.utilcode.util.BarUtils import com.blankj.utilcode.util.ServiceUtils import com.dylanc.activityresult.launcher.PickContentLauncher import com.dylanc.activityresult.launcher.StartActivityLauncher @@ -18,8 +26,6 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch -import li.songe.gkd.composition.CompositionActivity -import li.songe.gkd.composition.CompositionExt.useLifeCycleLog import li.songe.gkd.debug.FloatingService import li.songe.gkd.debug.HttpService import li.songe.gkd.debug.ScreenshotService @@ -31,58 +37,58 @@ import li.songe.gkd.service.updateLauncherAppId import li.songe.gkd.ui.NavGraphs import li.songe.gkd.ui.component.BuildDialog import li.songe.gkd.ui.theme.AppTheme -import li.songe.gkd.util.LocalLauncher -import li.songe.gkd.util.LocalMainViewModel import li.songe.gkd.util.LocalNavController -import li.songe.gkd.util.LocalPickContentLauncher import li.songe.gkd.util.UpgradeDialog import li.songe.gkd.util.initFolder import li.songe.gkd.util.launchTry import li.songe.gkd.util.map import li.songe.gkd.util.storeFlow -class MainActivity : CompositionActivity({ - this as MainActivity - useLifeCycleLog() - val launcher = StartActivityLauncher(this) - val pickContentLauncher = PickContentLauncher(this) - - lifecycleScope.launch { - storeFlow.map(lifecycleScope) { s -> s.excludeFromRecents }.collect { - (app.getSystemService(ACTIVITY_SERVICE) as ActivityManager).let { manager -> - manager.appTasks.forEach { task -> - task?.setExcludeFromRecents(it) +class MainActivity : ComponentActivity() { + val mainVm by viewModels() + val launcher by lazy { StartActivityLauncher(this) } + val pickContentLauncher by lazy { PickContentLauncher(this) } + + override fun onCreate(savedInstanceState: Bundle?) { + installSplashScreen() + enableEdgeToEdge() + fixTopPadding() + super.onCreate(savedInstanceState) + + lifecycleScope.launch { + storeFlow.map(lifecycleScope) { s -> s.excludeFromRecents }.collect { + (app.getSystemService(ACTIVITY_SERVICE) as ActivityManager).let { manager -> + manager.appTasks.forEach { task -> + task?.setExcludeFromRecents(it) + } } } } - } - ManageService.autoStart(this) - mainVm - - setContent { - val navController = rememberNavController() - AppTheme { - CompositionLocalProvider( - LocalLauncher provides launcher, - LocalPickContentLauncher provides pickContentLauncher, - LocalNavController provides navController, - LocalMainViewModel provides mainVm - ) { - DestinationsNavHost( - navGraph = NavGraphs.root, - navController = navController - ) - AuthDialog(mainVm.authReasonFlow) - BuildDialog(mainVm.dialogFlow) - if (BuildConfig.ENABLED_UPDATE) { - UpgradeDialog(mainVm.updateStatus) + mainVm + launcher + pickContentLauncher + ManageService.autoStart(this) + + setContent { + val navController = rememberNavController() + AppTheme { + CompositionLocalProvider( + LocalNavController provides navController + ) { + DestinationsNavHost( + navGraph = NavGraphs.root, + navController = navController + ) + AuthDialog(mainVm.authReasonFlow) + BuildDialog(mainVm.dialogFlow) + if (BuildConfig.ENABLED_UPDATE) { + UpgradeDialog(mainVm.updateStatus) + } } } } } -}) { - val mainVm by viewModels() override fun onResume() { super.onResume() @@ -154,3 +160,24 @@ private fun updateServiceRunning() { ScreenshotService.isRunning.value = ServiceUtils.isServiceRunning(ScreenshotService::class.java) HttpService.isRunning.value = ServiceUtils.isServiceRunning(HttpService::class.java) } + +private fun Activity.fixTopPadding() { + // 当调用系统分享时, 会导致状态栏区域消失, 应用整体上移, 设置一个 top padding 保证不上移 + var tempTop: Int? = null + ViewCompat.setOnApplyWindowInsetsListener(window.decorView) { view, windowInsets -> + view.setBackgroundColor(Color.TRANSPARENT) + val statusBars = windowInsets.getInsets(WindowInsetsCompat.Type.statusBars()) + if (statusBars.top == 0) { + view.setPadding( + statusBars.left, + tempTop ?: BarUtils.getStatusBarHeight(), + statusBars.right, + statusBars.bottom + ) + } else { + tempTop = statusBars.top + view.setPadding(statusBars.left, 0, statusBars.right, statusBars.bottom) + } + ViewCompat.onApplyWindowInsets(view, windowInsets) + } +} diff --git a/app/src/main/kotlin/li/songe/gkd/composition/CompositionActivity.kt b/app/src/main/kotlin/li/songe/gkd/composition/CompositionActivity.kt deleted file mode 100644 index 6e6e172d7..000000000 --- a/app/src/main/kotlin/li/songe/gkd/composition/CompositionActivity.kt +++ /dev/null @@ -1,71 +0,0 @@ -package li.songe.gkd.composition - -import android.content.res.Configuration -import android.graphics.Color -import android.os.Bundle -import androidx.activity.ComponentActivity -import androidx.activity.enableEdgeToEdge -import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen -import androidx.core.view.ViewCompat -import androidx.core.view.WindowInsetsCompat -import com.blankj.utilcode.util.BarUtils - -open class CompositionActivity( - private val block: CompositionActivity.(Bundle?) -> Unit, -) : ComponentActivity(), CanOnDestroy, CanOnConfigurationChanged { - - private val destroyHooks by lazy { linkedSetOf<() -> Unit>() } - override fun onDestroy(f: () -> Unit) = destroyHooks.add(f) - override fun onDestroy() { - super.onDestroy() - destroyHooks.forEach { f -> f() } - } - - private val finishHooks by lazy { linkedSetOf<(fs: () -> Unit) -> Unit>() } - fun onFinish(f: (fs: () -> Unit) -> Unit) = finishHooks.add(f) - override fun finish() { - if (finishHooks.isEmpty()) { - super.finish() - } - val fs = { super.finish() } - finishHooks.forEach { f -> f(fs) } - } - - override fun onCreate(savedInstanceState: Bundle?) { - installSplashScreen() - enableEdgeToEdge() - fixTopPadding() - super.onCreate(savedInstanceState) - block(savedInstanceState) - } - - private val configurationChangedHooks by lazy { linkedSetOf<(newConfig: Configuration) -> Unit>() } - override fun onConfigurationChanged(f: (newConfig: Configuration) -> Unit) = - configurationChangedHooks.add(f) - - override fun onConfigurationChanged(newConfig: Configuration) { - super.onConfigurationChanged(newConfig) - configurationChangedHooks.forEach { f -> f(newConfig) } - } -} - -fun ComponentActivity.fixTopPadding() { - // 当调用系统分享时, 会导致状态栏区域消失, 应用整体上移, 设置一个 top padding 保证不上移 - var tempTop: Int? = null - ViewCompat.setOnApplyWindowInsetsListener(window.decorView) { view, windowInsets -> - view.setBackgroundColor(Color.TRANSPARENT) - val statusBars = windowInsets.getInsets(WindowInsetsCompat.Type.statusBars()) - if (statusBars.top == 0) { - view.setPadding( - statusBars.left, - tempTop ?: BarUtils.getStatusBarHeight(), - statusBars.right, - statusBars.bottom - ) - } else { - tempTop = statusBars.top - view.setPadding(statusBars.left, 0, statusBars.right, statusBars.bottom) - } - ViewCompat.onApplyWindowInsets(view, windowInsets) - } -} diff --git a/app/src/main/kotlin/li/songe/gkd/composition/Typealias.kt b/app/src/main/kotlin/li/songe/gkd/composition/Typealias.kt index aca3fbca1..5d145f31b 100644 --- a/app/src/main/kotlin/li/songe/gkd/composition/Typealias.kt +++ b/app/src/main/kotlin/li/songe/gkd/composition/Typealias.kt @@ -1,11 +1,8 @@ package li.songe.gkd.composition -import android.content.Context import android.content.Intent import com.torrydo.floatingbubbleview.service.expandable.BubbleBuilder typealias StartCommandHook = (intent: Intent?, flags: Int, startId: Int) -> Unit -typealias onReceiveType = (Context?, Intent?) -> Unit - typealias ConfigBubbleHook = ((BubbleBuilder) -> Unit) -> Unit \ No newline at end of file diff --git a/app/src/main/kotlin/li/songe/gkd/ui/AdvancedPage.kt b/app/src/main/kotlin/li/songe/gkd/ui/AdvancedPage.kt index 214c4520d..3f5747e51 100644 --- a/app/src/main/kotlin/li/songe/gkd/ui/AdvancedPage.kt +++ b/app/src/main/kotlin/li/songe/gkd/ui/AdvancedPage.kt @@ -87,7 +87,6 @@ import li.songe.gkd.ui.destinations.SnapshotPageDestination import li.songe.gkd.ui.style.EmptyHeight import li.songe.gkd.ui.style.itemPadding import li.songe.gkd.ui.style.titleItemPadding -import li.songe.gkd.util.LocalLauncher import li.songe.gkd.util.LocalNavController import li.songe.gkd.util.ProfileTransitions import li.songe.gkd.util.appInfoCacheFlow @@ -111,7 +110,6 @@ import rikka.shizuku.Shizuku fun AdvancedPage() { val context = LocalContext.current as MainActivity val vm = viewModel() - val launcher = LocalLauncher.current val navController = LocalNavController.current val store by storeFlow.collectAsState() val snapshotCount by vm.snapshotCountFlow.collectAsState() @@ -443,7 +441,7 @@ fun AdvancedPage() { val mediaProjectionManager = context.getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager val activityResult = - launcher.launchForResult(mediaProjectionManager.createScreenCaptureIntent()) + context.launcher.launchForResult(mediaProjectionManager.createScreenCaptureIntent()) if (activityResult.resultCode == Activity.RESULT_OK && activityResult.data != null) { ScreenshotService.start(intent = activityResult.data!!) } diff --git a/app/src/main/kotlin/li/songe/gkd/ui/AppConfigPage.kt b/app/src/main/kotlin/li/songe/gkd/ui/AppConfigPage.kt index afc888ac6..3603458fb 100644 --- a/app/src/main/kotlin/li/songe/gkd/ui/AppConfigPage.kt +++ b/app/src/main/kotlin/li/songe/gkd/ui/AppConfigPage.kt @@ -43,6 +43,7 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.input.nestedscroll.nestedScroll +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp @@ -52,6 +53,7 @@ import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.annotation.RootNavGraph import com.ramcosta.composedestinations.navigation.navigate import kotlinx.coroutines.flow.update +import li.songe.gkd.MainActivity import li.songe.gkd.data.ExcludeData import li.songe.gkd.data.RawSubscription import li.songe.gkd.data.SubsConfig @@ -66,7 +68,6 @@ import li.songe.gkd.ui.style.itemVerticalPadding import li.songe.gkd.ui.style.menuPadding import li.songe.gkd.ui.style.titleItemPadding import li.songe.gkd.util.LOCAL_SUBS_ID -import li.songe.gkd.util.LocalMainViewModel import li.songe.gkd.util.LocalNavController import li.songe.gkd.util.ProfileTransitions import li.songe.gkd.util.ResolvedGroup @@ -299,7 +300,7 @@ private fun AppGroupCard( onClick: () -> Unit, onCheckedChange: ((Boolean) -> Unit)?, ) { - val mainVm = LocalMainViewModel.current + val context = LocalContext.current as MainActivity Row( modifier = Modifier .clickable(onClick = onClick) @@ -361,7 +362,7 @@ private fun AppGroupCard( interactionSource = remember { MutableInteractionSource() }, indication = null, ) { - mainVm.dialogFlow.updateDialogOptions( + context.mainVm.dialogFlow.updateDialogOptions( title = "内置禁用", text = "此规则组已经在其 apps 字段中配置对当前应用的禁用, 因此无法手动开启规则组\n\n提示: 这种情况一般在此全局规则无法适配/跳过适配/单独适配当前应用时出现", ) diff --git a/app/src/main/kotlin/li/songe/gkd/ui/AppItemPage.kt b/app/src/main/kotlin/li/songe/gkd/ui/AppItemPage.kt index aa17f87a8..727119ab8 100644 --- a/app/src/main/kotlin/li/songe/gkd/ui/AppItemPage.kt +++ b/app/src/main/kotlin/li/songe/gkd/ui/AppItemPage.kt @@ -48,6 +48,7 @@ import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.graphics.Color import androidx.compose.ui.input.nestedscroll.nestedScroll +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp @@ -61,6 +62,7 @@ import com.ramcosta.composedestinations.navigation.navigate import kotlinx.coroutines.Dispatchers import kotlinx.serialization.json.JsonArray import kotlinx.serialization.json.jsonObject +import li.songe.gkd.MainActivity import li.songe.gkd.data.ExcludeData import li.songe.gkd.data.RawSubscription import li.songe.gkd.data.SubsConfig @@ -71,7 +73,6 @@ import li.songe.gkd.ui.component.waitResult import li.songe.gkd.ui.destinations.GroupImagePageDestination import li.songe.gkd.ui.style.EmptyHeight import li.songe.gkd.ui.style.itemPadding -import li.songe.gkd.util.LocalMainViewModel import li.songe.gkd.util.LocalNavController import li.songe.gkd.util.ProfileTransitions import li.songe.gkd.util.appInfoCacheFlow @@ -93,8 +94,8 @@ fun AppItemPage( appId: String, focusGroupKey: Int? = null, // 背景/边框高亮一下 ) { + val context = LocalContext.current as MainActivity val navController = LocalNavController.current - val mainVm = LocalMainViewModel.current val vm = viewModel() val subsItem = vm.subsItemFlow.collectAsState().value val subsRaw = vm.subsRawFlow.collectAsState().value @@ -293,7 +294,7 @@ fun AppItemPage( onClick = { expanded = false vm.viewModelScope.launchTry { - mainVm.dialogFlow.waitResult( + context.mainVm.dialogFlow.waitResult( title = "删除规则组", text = "确定删除规则组 ${group.name} ?", error = true, diff --git a/app/src/main/kotlin/li/songe/gkd/ui/CategoryPage.kt b/app/src/main/kotlin/li/songe/gkd/ui/CategoryPage.kt index 80f6a8284..dd6275c6d 100644 --- a/app/src/main/kotlin/li/songe/gkd/ui/CategoryPage.kt +++ b/app/src/main/kotlin/li/songe/gkd/ui/CategoryPage.kt @@ -40,6 +40,7 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.input.nestedscroll.nestedScroll +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.lifecycle.viewModelScope @@ -47,6 +48,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.annotation.RootNavGraph import kotlinx.coroutines.Dispatchers +import li.songe.gkd.MainActivity import li.songe.gkd.data.CategoryConfig import li.songe.gkd.data.RawSubscription import li.songe.gkd.db.DbSet @@ -56,7 +58,6 @@ import li.songe.gkd.ui.component.waitResult 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.LocalMainViewModel import li.songe.gkd.util.LocalNavController import li.songe.gkd.util.ProfileTransitions import li.songe.gkd.util.findOption @@ -69,8 +70,8 @@ import li.songe.gkd.util.updateSubscription @Destination(style = ProfileTransitions::class) @Composable fun CategoryPage(subsItemId: Long) { + val context = LocalContext.current as MainActivity val navController = LocalNavController.current - val mainVm = LocalMainViewModel.current val vm = viewModel() val subsItem by vm.subsItemFlow.collectAsState() @@ -107,7 +108,7 @@ fun CategoryPage(subsItemId: Long) { ) }, actions = { IconButton(onClick = throttle { - mainVm.dialogFlow.updateDialogOptions( + context.mainVm.dialogFlow.updateDialogOptions( title = "开关优先级", text = "规则手动配置 > 分类手动配置 > 分类默认 > 规则默认\n\n重置开关: 移除规则手动配置", ) @@ -202,7 +203,7 @@ fun CategoryPage(subsItemId: Long) { }, onClick = { expanded = false vm.viewModelScope.launchTry { - mainVm.dialogFlow.waitResult( + context.mainVm.dialogFlow.waitResult( title = "删除类别", text = "确定删除 ${category.name} ?", error = true, diff --git a/app/src/main/kotlin/li/songe/gkd/ui/GlobalRulePage.kt b/app/src/main/kotlin/li/songe/gkd/ui/GlobalRulePage.kt index 17685d509..309ee8e1a 100644 --- a/app/src/main/kotlin/li/songe/gkd/ui/GlobalRulePage.kt +++ b/app/src/main/kotlin/li/songe/gkd/ui/GlobalRulePage.kt @@ -48,6 +48,7 @@ import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.graphics.Color import androidx.compose.ui.input.nestedscroll.nestedScroll +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp @@ -60,6 +61,7 @@ import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.annotation.RootNavGraph import com.ramcosta.composedestinations.navigation.navigate import kotlinx.coroutines.Dispatchers +import li.songe.gkd.MainActivity import li.songe.gkd.data.RawSubscription import li.songe.gkd.data.SubsConfig import li.songe.gkd.db.DbSet @@ -69,7 +71,6 @@ import li.songe.gkd.ui.destinations.GlobalRuleExcludePageDestination import li.songe.gkd.ui.destinations.GroupImagePageDestination import li.songe.gkd.ui.style.EmptyHeight import li.songe.gkd.ui.style.itemPadding -import li.songe.gkd.util.LocalMainViewModel import li.songe.gkd.util.LocalNavController import li.songe.gkd.util.ProfileTransitions import li.songe.gkd.util.json @@ -84,8 +85,8 @@ import li.songe.json5.encodeToJson5String @Destination(style = ProfileTransitions::class) @Composable fun GlobalRulePage(subsItemId: Long, focusGroupKey: Int? = null) { + val context = LocalContext.current as MainActivity val navController = LocalNavController.current - val mainVm = LocalMainViewModel.current val vm = viewModel() val subsItem by vm.subsItemFlow.collectAsState() val rawSubs = vm.subsRawFlow.collectAsState().value @@ -254,7 +255,7 @@ fun GlobalRulePage(subsItemId: Long, focusGroupKey: Int? = null) { onClick = { expanded = false vm.viewModelScope.launchTry { - mainVm.dialogFlow.waitResult( + context.mainVm.dialogFlow.waitResult( title = "删除规则组", text = "确定删除 ${group.name} ?", error = true, diff --git a/app/src/main/kotlin/li/songe/gkd/ui/SlowGroupPage.kt b/app/src/main/kotlin/li/songe/gkd/ui/SlowGroupPage.kt index 020442077..5ae08627b 100644 --- a/app/src/main/kotlin/li/songe/gkd/ui/SlowGroupPage.kt +++ b/app/src/main/kotlin/li/songe/gkd/ui/SlowGroupPage.kt @@ -27,17 +27,18 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.input.nestedscroll.nestedScroll +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.annotation.RootNavGraph import com.ramcosta.composedestinations.navigation.navigate +import li.songe.gkd.MainActivity import li.songe.gkd.ui.component.updateDialogOptions import li.songe.gkd.ui.destinations.AppItemPageDestination import li.songe.gkd.ui.destinations.GlobalRulePageDestination import li.songe.gkd.ui.style.EmptyHeight import li.songe.gkd.ui.style.itemPadding -import li.songe.gkd.util.LocalMainViewModel import li.songe.gkd.util.LocalNavController import li.songe.gkd.util.ProfileTransitions import li.songe.gkd.util.appInfoCacheFlow @@ -48,8 +49,8 @@ import li.songe.gkd.util.throttle @Destination(style = ProfileTransitions::class) @Composable fun SlowGroupPage() { + val context = LocalContext.current as MainActivity val navController = LocalNavController.current - val mainVm = LocalMainViewModel.current val ruleSummary by ruleSummaryFlow.collectAsState() val appInfoCache by appInfoCacheFlow.collectAsState() @@ -72,7 +73,7 @@ fun SlowGroupPage() { title = { Text(text = if (ruleSummary.slowGroupCount > 0) "缓慢查询-${ruleSummary.slowGroupCount}" else "缓慢查询") }, actions = { IconButton(onClick = throttle { - mainVm.dialogFlow.updateDialogOptions( + context.mainVm.dialogFlow.updateDialogOptions( title = "缓慢查询", text = "任意单个规则同时满足以下 3 个条件即判定为缓慢查询\n\n1. 选择器右侧无法快速查询且不是主动查询, 或内部使用<<且无法快速查询\n2. preKeys 为空\n3. matchTime 为空或大于 10s", ) diff --git a/app/src/main/kotlin/li/songe/gkd/ui/SnapshotPage.kt b/app/src/main/kotlin/li/songe/gkd/ui/SnapshotPage.kt index 7d996707b..0c4aafd00 100644 --- a/app/src/main/kotlin/li/songe/gkd/ui/SnapshotPage.kt +++ b/app/src/main/kotlin/li/songe/gkd/ui/SnapshotPage.kt @@ -61,7 +61,6 @@ import li.songe.gkd.ui.destinations.ImagePreviewPageDestination import li.songe.gkd.ui.style.EmptyHeight import li.songe.gkd.util.IMPORT_SHORT_URL 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.saveFileToDownloads @@ -78,8 +77,6 @@ fun SnapshotPage() { val navController = LocalNavController.current val colorScheme = MaterialTheme.colorScheme - val pickContentLauncher = LocalPickContentLauncher.current - val vm = viewModel() val snapshots by vm.snapshotsState.collectAsState() @@ -288,7 +285,7 @@ fun SnapshotPage() { text = "替换截图(去除隐私)", modifier = Modifier .clickable(onClick = vm.viewModelScope.launchAsFn { - val uri = pickContentLauncher.launchForImageResult() + val uri = context.pickContentLauncher.launchForImageResult() withContext(Dispatchers.IO) { val oldBitmap = ImageUtils.getBitmap(snapshotVal.screenshotFile) val newBytes = UriUtils.uri2Bytes(uri) diff --git a/app/src/main/kotlin/li/songe/gkd/ui/SubsPage.kt b/app/src/main/kotlin/li/songe/gkd/ui/SubsPage.kt index c4ebfd576..ba06339ad 100644 --- a/app/src/main/kotlin/li/songe/gkd/ui/SubsPage.kt +++ b/app/src/main/kotlin/li/songe/gkd/ui/SubsPage.kt @@ -43,6 +43,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.input.nestedscroll.nestedScroll +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.style.TextAlign import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewmodel.compose.viewModel @@ -50,6 +51,7 @@ 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.MainActivity import li.songe.gkd.data.RawSubscription import li.songe.gkd.data.SubsConfig import li.songe.gkd.db.DbSet @@ -60,7 +62,6 @@ import li.songe.gkd.ui.component.waitResult 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.LocalMainViewModel import li.songe.gkd.util.LocalNavController import li.songe.gkd.util.ProfileTransitions import li.songe.gkd.util.SortTypeOption @@ -80,8 +81,8 @@ import li.songe.json5.encodeToJson5String fun SubsPage( subsItemId: Long, ) { + val context = LocalContext.current as MainActivity val navController = LocalNavController.current - val mainVm = LocalMainViewModel.current val vm = viewModel() val subsItem = vm.subsItemFlow.collectAsState().value @@ -266,7 +267,7 @@ fun SubsPage( }), showMenu = editable, onDelClick = throttle(fn = vm.viewModelScope.launchAsFn { - mainVm.dialogFlow.waitResult( + context.mainVm.dialogFlow.waitResult( title = "删除规则组", text = "确定删除 ${appInfoCache[appRaw.id]?.name ?: appRaw.name ?: appRaw.id} 下所有规则组?", error = true, diff --git a/app/src/main/kotlin/li/songe/gkd/ui/component/SubsItemCard.kt b/app/src/main/kotlin/li/songe/gkd/ui/component/SubsItemCard.kt index fc106fb85..57bea958f 100644 --- a/app/src/main/kotlin/li/songe/gkd/ui/component/SubsItemCard.kt +++ b/app/src/main/kotlin/li/songe/gkd/ui/component/SubsItemCard.kt @@ -39,6 +39,7 @@ import androidx.lifecycle.viewModelScope import com.blankj.utilcode.util.ClipboardUtils import com.ramcosta.composedestinations.navigation.navigate import kotlinx.coroutines.Dispatchers +import li.songe.gkd.MainActivity import li.songe.gkd.data.RawSubscription import li.songe.gkd.data.SubsItem import li.songe.gkd.data.deleteSubscription @@ -47,7 +48,6 @@ import li.songe.gkd.ui.destinations.GlobalRulePageDestination import li.songe.gkd.ui.destinations.SubsPageDestination import li.songe.gkd.ui.home.HomeVm import li.songe.gkd.util.LOCAL_SUBS_ID -import li.songe.gkd.util.LocalMainViewModel import li.songe.gkd.util.LocalNavController import li.songe.gkd.util.formatTimeAgo import li.songe.gkd.util.launchTry @@ -215,8 +215,7 @@ private fun SubsMenuItem( vm: HomeVm ) { val navController = LocalNavController.current - val context = LocalContext.current - val mainVm = LocalMainViewModel.current + val context = LocalContext.current as MainActivity val density = LocalDensity.current var halfMenuWidth by remember { mutableStateOf(0.dp) @@ -307,7 +306,7 @@ private fun SubsMenuItem( onClick = { onExpandedChange(false) vm.viewModelScope.launchTry { - mainVm.dialogFlow.waitResult( + context.mainVm.dialogFlow.waitResult( title = "删除订阅", text = "确定删除 ${subscription?.name ?: subItem.id} ?", error = true, diff --git a/app/src/main/kotlin/li/songe/gkd/ui/home/SettingsPage.kt b/app/src/main/kotlin/li/songe/gkd/ui/home/SettingsPage.kt index 25ac5812a..98e9a3cfc 100644 --- a/app/src/main/kotlin/li/songe/gkd/ui/home/SettingsPage.kt +++ b/app/src/main/kotlin/li/songe/gkd/ui/home/SettingsPage.kt @@ -31,12 +31,14 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.input.nestedscroll.nestedScroll +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.style.TextAlign import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewmodel.compose.viewModel import com.ramcosta.composedestinations.navigation.navigate import kotlinx.coroutines.flow.update import li.songe.gkd.BuildConfig +import li.songe.gkd.MainActivity import li.songe.gkd.ui.component.RotatingLoadingIcon import li.songe.gkd.ui.component.SettingItem import li.songe.gkd.ui.component.TextMenu @@ -50,7 +52,6 @@ import li.songe.gkd.ui.style.itemPadding import li.songe.gkd.ui.style.titleItemPadding import li.songe.gkd.ui.theme.supportDynamicColor import li.songe.gkd.util.DarkThemeOption -import li.songe.gkd.util.LocalMainViewModel import li.songe.gkd.util.LocalNavController import li.songe.gkd.util.UpdateChannelOption import li.songe.gkd.util.checkUpdate @@ -67,7 +68,7 @@ val settingsNav = BottomNavItem( @Composable fun useSettingsPage(): ScaffoldExt { - val mainVm = LocalMainViewModel.current + val context = LocalContext.current as MainActivity val navController = LocalNavController.current val store by storeFlow.collectAsState() val vm = viewModel() @@ -79,7 +80,7 @@ fun useSettingsPage(): ScaffoldExt { mutableStateOf(false) } - val checkUpdating by mainVm.updateStatus.checkUpdatingFlow.collectAsState() + val checkUpdating by context.mainVm.updateStatus.checkUpdatingFlow.collectAsState() if (showToastInputDlg) { var value by remember { @@ -138,7 +139,7 @@ fun useSettingsPage(): ScaffoldExt { ) { Text(text = "通知文案") IconButton(onClick = throttle { - mainVm.dialogFlow.updateDialogOptions( + context.mainVm.dialogFlow.updateDialogOptions( title = "文案规则", text = "通知文案支持变量替换,规则如下\n\${i} 全局规则数\n\${k} 应用数\n\${u} 应用规则组数\n\${n} 触发次数\n\n示例模板\n\${i}全局/\${k}应用/\${u}规则组/\${n}触发\n\n替换结果\n0全局/1应用/2规则组/3触发", ) @@ -234,7 +235,7 @@ fun useSettingsPage(): ScaffoldExt { subtitle = "系统样式触发提示", suffix = "查看限制", onSuffixClick = { - mainVm.dialogFlow.updateDialogOptions( + context.mainVm.dialogFlow.updateDialogOptions( title = "限制说明", text = "系统 Toast 存在频率限制, 触发过于频繁会被系统强制不显示\n\n如果只使用开屏一类低频率规则可使用系统提示, 否则建议关闭此项使用自定义样式提示", ) @@ -321,7 +322,7 @@ fun useSettingsPage(): ScaffoldExt { ) { if (it.value == UpdateChannelOption.Beta.value) { vm.viewModelScope.launchTry { - mainVm.dialogFlow.waitResult( + context.mainVm.dialogFlow.waitResult( title = "版本渠道", text = "测试版本渠道更新快\n但不稳定可能存在较多BUG\n请谨慎使用", ) @@ -335,9 +336,9 @@ fun useSettingsPage(): ScaffoldExt { Row( modifier = Modifier .clickable( - onClick = throttle(fn = mainVm.viewModelScope.launchAsFn { - if (mainVm.updateStatus.checkUpdatingFlow.value) return@launchAsFn - val newVersion = mainVm.updateStatus.checkUpdate() + onClick = throttle(fn = context.mainVm.viewModelScope.launchAsFn { + if (context.mainVm.updateStatus.checkUpdatingFlow.value) return@launchAsFn + val newVersion = context.mainVm.updateStatus.checkUpdate() if (newVersion == null) { toast("暂无更新") } diff --git a/app/src/main/kotlin/li/songe/gkd/ui/home/SubsManagePage.kt b/app/src/main/kotlin/li/songe/gkd/ui/home/SubsManagePage.kt index 19436bc3f..7bc2dae71 100644 --- a/app/src/main/kotlin/li/songe/gkd/ui/home/SubsManagePage.kt +++ b/app/src/main/kotlin/li/songe/gkd/ui/home/SubsManagePage.kt @@ -72,8 +72,6 @@ import li.songe.gkd.ui.component.TextMenu import li.songe.gkd.ui.component.waitResult import li.songe.gkd.ui.style.itemVerticalPadding import li.songe.gkd.util.LOCAL_SUBS_ID -import li.songe.gkd.util.LocalLauncher -import li.songe.gkd.util.LocalMainViewModel import li.songe.gkd.util.SafeR import li.songe.gkd.util.UpdateTimeOption import li.songe.gkd.util.checkSubsUpdate @@ -98,8 +96,7 @@ val subsNav = BottomNavItem( @Composable fun useSubsManagePage(): ScaffoldExt { - val launcher = LocalLauncher.current - val mainVm = LocalMainViewModel.current + val context = LocalContext.current as MainActivity val vm = viewModel() val subItems by subsItemsFlow.collectAsState() @@ -175,7 +172,7 @@ fun useSubsManagePage(): ScaffoldExt { } vm.viewModelScope.launchTry { if (!isSafeUrl(link)) { - mainVm.dialogFlow.waitResult( + context.mainVm.dialogFlow.waitResult( title = "未知来源", text = "你正在添加一个未验证的远程订阅\n\n这可能含有恶意的规则\n\n是否仍然确认添加?" ) @@ -251,7 +248,7 @@ fun useSubsManagePage(): ScaffoldExt { if (selectedIds.contains(LOCAL_SUBS_ID)) "$it\n\n注: 不包含本地订阅" else it } IconButton(onClick = vm.viewModelScope.launchAsFn { - mainVm.dialogFlow.waitResult( + context.mainVm.dialogFlow.waitResult( title = "删除订阅", text = text, error = true, @@ -348,7 +345,7 @@ fun useSubsManagePage(): ScaffoldExt { onClick = vm.viewModelScope.launchAsFn(Dispatchers.IO) { expanded = false val result = - launcher.launchForResult(Intent(Intent.ACTION_OPEN_DOCUMENT).apply { + context.launcher.launchForResult(Intent(Intent.ACTION_OPEN_DOCUMENT).apply { addCategory(Intent.CATEGORY_OPENABLE) type = "application/zip" }) diff --git a/app/src/main/kotlin/li/songe/gkd/util/ComposeExt.kt b/app/src/main/kotlin/li/songe/gkd/util/ComposeExt.kt index 7b9afe7e1..3138a1125 100644 --- a/app/src/main/kotlin/li/songe/gkd/util/ComposeExt.kt +++ b/app/src/main/kotlin/li/songe/gkd/util/ComposeExt.kt @@ -1,15 +1,2 @@ package li.songe.gkd.util -import androidx.compose.runtime.compositionLocalOf -import com.dylanc.activityresult.launcher.PickContentLauncher -import com.dylanc.activityresult.launcher.StartActivityLauncher -import li.songe.gkd.MainViewModel - - -val LocalLauncher = - compositionLocalOf { error("not found StartActivityLauncher") } - -val LocalPickContentLauncher = - compositionLocalOf { error("not found LocalPickContentLauncher") } - -val LocalMainViewModel = compositionLocalOf { error("not found LocalMainViewModel") } diff --git a/app/src/main/kotlin/li/songe/gkd/util/Upgrade.kt b/app/src/main/kotlin/li/songe/gkd/util/Upgrade.kt index e033e39da..3870cd34a 100644 --- a/app/src/main/kotlin/li/songe/gkd/util/Upgrade.kt +++ b/app/src/main/kotlin/li/songe/gkd/util/Upgrade.kt @@ -14,6 +14,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp import androidx.core.content.FileProvider import androidx.lifecycle.viewModelScope @@ -31,6 +32,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import kotlinx.serialization.Serializable import li.songe.gkd.BuildConfig +import li.songe.gkd.MainActivity import li.songe.gkd.MainViewModel import li.songe.gkd.app import java.io.File @@ -122,7 +124,7 @@ private fun UpdateStatus.startDownload(viewModel: MainViewModel, newVersion: New @Composable fun UpgradeDialog(status: UpdateStatus) { - val mainVm = LocalMainViewModel.current + val context = LocalContext.current as MainActivity val newVersion by status.newVersionFlow.collectAsState() newVersion?.let { newVersionVal -> AlertDialog(title = { @@ -145,7 +147,7 @@ fun UpgradeDialog(status: UpdateStatus) { }, onDismissRequest = { }, confirmButton = { TextButton(onClick = { status.newVersionFlow.value = null - status.startDownload(mainVm, newVersionVal) + status.startDownload(context.mainVm, newVersionVal) }) { Text(text = "下载更新") }