mirror of
https://github.com/gkd-kit/gkd.git
synced 2024-11-16 03:32:38 +08:00
This commit is contained in:
parent
001bb5683d
commit
75a6a3dad4
|
@ -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
|
||||||
})
|
})
|
||||||
|
|
|
@ -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,27 +482,36 @@ private fun ShizukuFragment(enabled: Boolean = true) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showShizukuErrorDialog(dialog: DialogApiInjection) {
|
@Composable
|
||||||
|
private fun ShizukuErrorDialog(stateFlow: MutableStateFlow<Boolean>) {
|
||||||
|
val state = stateFlow.collectAsState()
|
||||||
|
if (state.value) {
|
||||||
val appId = "moe.shizuku.privileged.api"
|
val appId = "moe.shizuku.privileged.api"
|
||||||
val installed = appInfoCacheFlow.value.contains(appId)
|
val appInfoCache = appInfoCacheFlow.collectAsState()
|
||||||
dialog.build(
|
val installed = appInfoCache.value.contains(appId)
|
||||||
title = "授权错误",
|
AlertDialog(
|
||||||
|
onDismissRequest = { stateFlow.value = false },
|
||||||
|
title = { Text(text = "授权错误") },
|
||||||
|
text = {
|
||||||
|
Text(
|
||||||
text = if (installed) {
|
text = if (installed) {
|
||||||
"Shizuku 授权失败, 请检查是否运行"
|
"Shizuku 授权失败, 请检查是否运行"
|
||||||
} else {
|
} else {
|
||||||
"Shizuku 未安装, 请先下载后安装"
|
"Shizuku 未安装, 请先下载后安装"
|
||||||
|
}
|
||||||
|
)
|
||||||
},
|
},
|
||||||
confirmButton = {
|
confirmButton = {
|
||||||
if (installed) {
|
if (installed) {
|
||||||
TextButton(onClick = {
|
TextButton(onClick = {
|
||||||
dialog.dismiss()
|
stateFlow.value = false
|
||||||
app.openApp(appId)
|
app.openApp(appId)
|
||||||
}) {
|
}) {
|
||||||
Text(text = "打开 Shizuku")
|
Text(text = "打开 Shizuku")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TextButton(onClick = {
|
TextButton(onClick = {
|
||||||
dialog.dismiss()
|
stateFlow.value = false
|
||||||
app.openUri("https://shizuku.rikka.app/")
|
app.openUri("https://shizuku.rikka.app/")
|
||||||
}) {
|
}) {
|
||||||
Text(text = "去下载")
|
Text(text = "去下载")
|
||||||
|
@ -511,9 +519,10 @@ private fun showShizukuErrorDialog(dialog: DialogApiInjection) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
dismissButton = {
|
dismissButton = {
|
||||||
TextButton(onClick = dialog.dismiss) {
|
TextButton(onClick = { stateFlow.value = false }) {
|
||||||
Text(text = "我知道了")
|
Text(text = "我知道了")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
|
@ -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
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user