perf: shizuku dialog
Some checks failed
Build-Apk / build (push) Has been cancelled

This commit is contained in:
lisonge 2024-07-30 15:53:02 +08:00
parent 001bb5683d
commit 75a6a3dad4
4 changed files with 50 additions and 111 deletions

View File

@ -125,8 +125,7 @@ val shizukuOkState by lazy {
check = { check = {
shizukuIsSafeOK() && (try { shizukuIsSafeOK() && (try {
// 打开 shizuku 点击右上角停止, 此时 shizukuIsSafeOK() == true, 因此需要二次检查状态 // 打开 shizuku 点击右上角停止, 此时 shizukuIsSafeOK() == true, 因此需要二次检查状态
newActivityTaskManager()?.safeGetTasks(log = false) newActivityTaskManager()?.safeGetTasks(log = false)?.isNotEmpty() == true
true
} catch (e: Exception) { } catch (e: Exception) {
false false
}) })

View File

@ -55,6 +55,7 @@ import com.dylanc.activityresult.launcher.launchForResult
import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootNavGraph import com.ramcosta.composedestinations.annotation.RootNavGraph
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.update import kotlinx.coroutines.flow.update
import li.songe.gkd.MainActivity import li.songe.gkd.MainActivity
import li.songe.gkd.app import li.songe.gkd.app
@ -71,11 +72,8 @@ import li.songe.gkd.shizuku.newActivityTaskManager
import li.songe.gkd.shizuku.newUserService import li.songe.gkd.shizuku.newUserService
import li.songe.gkd.shizuku.safeGetTasks import li.songe.gkd.shizuku.safeGetTasks
import li.songe.gkd.ui.component.AuthCard import li.songe.gkd.ui.component.AuthCard
import li.songe.gkd.ui.component.DialogApiInjection
import li.songe.gkd.ui.component.SettingItem import li.songe.gkd.ui.component.SettingItem
import li.songe.gkd.ui.component.TextSwitch import li.songe.gkd.ui.component.TextSwitch
import li.songe.gkd.ui.component.build
import li.songe.gkd.ui.component.useDialog
import li.songe.gkd.ui.destinations.SnapshotPageDestination import li.songe.gkd.ui.destinations.SnapshotPageDestination
import li.songe.gkd.ui.style.itemPadding import li.songe.gkd.ui.style.itemPadding
import li.songe.gkd.ui.style.titleItemPadding import li.songe.gkd.ui.style.titleItemPadding
@ -98,14 +96,15 @@ import rikka.shizuku.Shizuku
@Composable @Composable
fun AdvancedPage() { fun AdvancedPage() {
val context = LocalContext.current as MainActivity val context = LocalContext.current as MainActivity
val vm = hiltViewModel<AdvancedVm>()
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val dialog = useDialog()
val launcher = LocalLauncher.current val launcher = LocalLauncher.current
val navController = LocalNavController.current val navController = LocalNavController.current
val store by storeFlow.collectAsState() val store by storeFlow.collectAsState()
val vm = hiltViewModel<AdvancedVm>()
val snapshotCount by vm.snapshotCountFlow.collectAsState() val snapshotCount by vm.snapshotCountFlow.collectAsState()
ShizukuErrorDialog(vm.shizukuErrorFlow)
var showPortDlg by remember { var showPortDlg by remember {
mutableStateOf(false) mutableStateOf(false)
} }
@ -147,7 +146,7 @@ fun AdvancedPage() {
Shizuku.requestPermission(Activity.RESULT_OK) Shizuku.requestPermission(Activity.RESULT_OK)
} catch (e: Exception) { } catch (e: Exception) {
LogUtils.d("Shizuku授权错误", e.message) LogUtils.d("Shizuku授权错误", e.message)
showShizukuErrorDialog(dialog) vm.shizukuErrorFlow.value = true
} }
}) })
ShizukuFragment(false) ShizukuFragment(false)
@ -483,37 +482,47 @@ private fun ShizukuFragment(enabled: Boolean = true) {
} }
private fun showShizukuErrorDialog(dialog: DialogApiInjection) { @Composable
val appId = "moe.shizuku.privileged.api" private fun ShizukuErrorDialog(stateFlow: MutableStateFlow<Boolean>) {
val installed = appInfoCacheFlow.value.contains(appId) val state = stateFlow.collectAsState()
dialog.build( if (state.value) {
title = "授权错误", val appId = "moe.shizuku.privileged.api"
text = if (installed) { val appInfoCache = appInfoCacheFlow.collectAsState()
"Shizuku 授权失败, 请检查是否运行" val installed = appInfoCache.value.contains(appId)
} else { AlertDialog(
"Shizuku 未安装, 请先下载后安装" onDismissRequest = { stateFlow.value = false },
}, title = { Text(text = "授权错误") },
confirmButton = { text = {
if (installed) { Text(
TextButton(onClick = { text = if (installed) {
dialog.dismiss() "Shizuku 授权失败, 请检查是否运行"
app.openApp(appId) } else {
}) { "Shizuku 未安装, 请先下载后安装"
Text(text = "打开 Shizuku") }
)
},
confirmButton = {
if (installed) {
TextButton(onClick = {
stateFlow.value = false
app.openApp(appId)
}) {
Text(text = "打开 Shizuku")
}
} else {
TextButton(onClick = {
stateFlow.value = false
app.openUri("https://shizuku.rikka.app/")
}) {
Text(text = "去下载")
}
} }
} else { },
TextButton(onClick = { dismissButton = {
dialog.dismiss() TextButton(onClick = { stateFlow.value = false }) {
app.openUri("https://shizuku.rikka.app/") Text(text = "我知道了")
}) {
Text(text = "去下载")
} }
} }
}, )
dismissButton = { }
TextButton(onClick = dialog.dismiss) {
Text(text = "我知道了")
}
}
)
} }

View File

@ -4,6 +4,7 @@ import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn
import li.songe.gkd.db.DbSet import li.songe.gkd.db.DbSet
@ -13,4 +14,6 @@ import javax.inject.Inject
class AdvancedVm @Inject constructor(stateHandle: SavedStateHandle) : ViewModel() { class AdvancedVm @Inject constructor(stateHandle: SavedStateHandle) : ViewModel() {
val snapshotCountFlow = val snapshotCountFlow =
DbSet.snapshotDao.count().stateIn(viewModelScope, SharingStarted.Eagerly, 0) DbSet.snapshotDao.count().stateIn(viewModelScope, SharingStarted.Eagerly, 0)
val shizukuErrorFlow = MutableStateFlow(false)
} }

View File

@ -1,72 +0,0 @@
package li.songe.gkd.ui.component
import androidx.compose.foundation.Image
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.graphics.vector.ImageVector
data class DialogOptions internal constructor(
val onDismissRequest: (() -> Unit)? = null,
val confirmButton: @Composable () -> Unit,
val dismissButton: @Composable (() -> Unit)? = null,
val icon: @Composable (() -> Unit)? = null,
val title: @Composable (() -> Unit)? = null,
val text: @Composable (() -> Unit)? = null,
)
class DialogApiInjection(
val create: (options: DialogOptions) -> Unit,
val dismiss: () -> Unit,
)
fun DialogApiInjection.build(
title: String,
text: String,
confirmButton: @Composable () -> Unit,
dismissButton: @Composable (() -> Unit)? = null,
icon: ImageVector? = null,
) {
return create(
DialogOptions(
confirmButton = confirmButton,
dismissButton = dismissButton,
icon = icon?.let {
{ Image(imageVector = icon, contentDescription = null) }
},
title = {
Text(text = title)
},
text = {
Text(text = text)
},
)
)
}
@Composable
fun useDialog(): DialogApiInjection {
var options by remember { mutableStateOf<DialogOptions?>(null) }
val apiInjection = remember {
DialogApiInjection(
create = { options = it },
dismiss = { options = null }
)
}
options?.let {
AlertDialog(
onDismissRequest = it.onDismissRequest ?: apiInjection.dismiss,
confirmButton = it.confirmButton,
dismissButton = it.dismissButton,
icon = it.icon,
title = it.title,
text = it.text,
)
}
return apiInjection
}