manager: refine dialog component and make a small fix in AboutCard (#422)
Co-authored-by: weishu <twsxtd@gmail.com>
This commit is contained in:
@@ -3,16 +3,23 @@ package me.weishu.kernelsu.ui.component
|
|||||||
import android.text.method.LinkMovementMethod
|
import android.text.method.LinkMovementMethod
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material3.ElevatedCard
|
import androidx.compose.material3.ElevatedCard
|
||||||
import androidx.compose.material3.LocalTextStyle
|
import androidx.compose.material3.LocalContentColor
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
|
||||||
import androidx.compose.runtime.MutableState
|
import androidx.compose.runtime.MutableState
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.toArgb
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
@@ -59,46 +66,43 @@ private fun AboutCardContent() {
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
) {
|
) {
|
||||||
CompositionLocalProvider(LocalTextStyle provides MaterialTheme.typography.bodyMedium) {
|
val drawable = ResourcesCompat.getDrawable(
|
||||||
|
LocalContext.current.resources,
|
||||||
|
R.mipmap.ic_launcher,
|
||||||
|
LocalContext.current.theme
|
||||||
|
)
|
||||||
|
|
||||||
val drawable = ResourcesCompat.getDrawable(
|
Row {
|
||||||
LocalContext.current.resources,
|
Image(
|
||||||
R.mipmap.ic_launcher,
|
painter = rememberDrawablePainter(drawable),
|
||||||
LocalContext.current.theme
|
contentDescription = "icon",
|
||||||
|
modifier = Modifier.size(40.dp)
|
||||||
)
|
)
|
||||||
|
|
||||||
Row {
|
Spacer(modifier = Modifier.width(12.dp))
|
||||||
Image(
|
|
||||||
painter = rememberDrawablePainter(drawable),
|
Column {
|
||||||
contentDescription = "icon",
|
|
||||||
modifier = Modifier.size(40.dp)
|
Text(
|
||||||
|
stringResource(id = R.string.app_name),
|
||||||
|
style = MaterialTheme.typography.titleSmall,
|
||||||
|
fontSize = 18.sp
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
BuildConfig.VERSION_NAME,
|
||||||
|
style = MaterialTheme.typography.bodySmall,
|
||||||
|
fontSize = 14.sp
|
||||||
)
|
)
|
||||||
|
|
||||||
Spacer(modifier = Modifier.width(12.dp))
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
|
||||||
Column {
|
HtmlText(
|
||||||
|
html = stringResource(
|
||||||
Text(
|
id = R.string.about_source_code,
|
||||||
stringResource(id = R.string.app_name),
|
"<b><a href=\"https://github.com/tiann/KernelSU\">GitHub</a></b>",
|
||||||
style = MaterialTheme.typography.titleSmall,
|
"<b><a href=\"https://t.me/KernelSU\">Telegram</a></b>"
|
||||||
fontSize = 18.sp
|
|
||||||
)
|
)
|
||||||
Text(
|
)
|
||||||
BuildConfig.VERSION_NAME,
|
|
||||||
style = MaterialTheme.typography.bodySmall,
|
|
||||||
fontSize = 14.sp
|
|
||||||
)
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
|
||||||
|
|
||||||
HtmlText(
|
|
||||||
html = stringResource(
|
|
||||||
id = R.string.about_source_code,
|
|
||||||
"<b><a href=\"https://github.com/tiann/KernelSU\">GitHub</a></b>",
|
|
||||||
"<b><a href=\"https://t.me/KernelSU\">Telegram</a></b>"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,6 +110,7 @@ private fun AboutCardContent() {
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun HtmlText(html: String, modifier: Modifier = Modifier) {
|
fun HtmlText(html: String, modifier: Modifier = Modifier) {
|
||||||
|
val contentColor = LocalContentColor.current
|
||||||
AndroidView(
|
AndroidView(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
factory = { context ->
|
factory = { context ->
|
||||||
@@ -113,6 +118,9 @@ fun HtmlText(html: String, modifier: Modifier = Modifier) {
|
|||||||
it.movementMethod = LinkMovementMethod.getInstance()
|
it.movementMethod = LinkMovementMethod.getInstance()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
update = { it.text = HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_COMPACT) }
|
update = {
|
||||||
|
it.text = HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_COMPACT)
|
||||||
|
it.setTextColor(contentColor.toArgb())
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1,56 +1,113 @@
|
|||||||
package me.weishu.kernelsu.ui.component
|
package me.weishu.kernelsu.ui.component
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material3.AlertDialog
|
import androidx.compose.material3.AlertDialog
|
||||||
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextButton
|
import androidx.compose.material3.TextButton
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.window.Dialog
|
||||||
|
import androidx.compose.ui.window.DialogProperties
|
||||||
import kotlinx.coroutines.CancellableContinuation
|
import kotlinx.coroutines.CancellableContinuation
|
||||||
|
import kotlinx.coroutines.coroutineScope
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import kotlinx.coroutines.sync.withLock
|
import kotlinx.coroutines.sync.withLock
|
||||||
import me.weishu.kernelsu.ui.util.LocalDialogHost
|
import me.weishu.kernelsu.ui.util.LocalDialogHost
|
||||||
import kotlin.coroutines.resume
|
import kotlin.coroutines.resume
|
||||||
|
|
||||||
sealed interface DialogResult {
|
interface DialogVisuals
|
||||||
object Confirmed : DialogResult
|
|
||||||
object Dismissed : DialogResult
|
|
||||||
}
|
|
||||||
|
|
||||||
interface DialogVisuals {
|
interface LoadingDialogVisuals : DialogVisuals
|
||||||
|
|
||||||
|
interface PromptDialogVisuals : DialogVisuals {
|
||||||
val title: String
|
val title: String
|
||||||
val content: String
|
val content: String
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ConfirmDialogVisuals : PromptDialogVisuals {
|
||||||
val confirm: String?
|
val confirm: String?
|
||||||
val dismiss: String?
|
val dismiss: String?
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DialogData {
|
|
||||||
|
sealed interface DialogData {
|
||||||
val visuals: DialogVisuals
|
val visuals: DialogVisuals
|
||||||
|
}
|
||||||
|
|
||||||
fun confirm()
|
interface LoadingDialogData : DialogData {
|
||||||
|
override val visuals: LoadingDialogVisuals
|
||||||
fun dismiss()
|
fun dismiss()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface PromptDialogData : DialogData {
|
||||||
|
override val visuals: PromptDialogVisuals
|
||||||
|
fun dismiss()
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ConfirmDialogData : PromptDialogData {
|
||||||
|
override val visuals: ConfirmDialogVisuals
|
||||||
|
fun confirm()
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed interface ConfirmResult {
|
||||||
|
object Confirmed : ConfirmResult
|
||||||
|
object Canceled : ConfirmResult
|
||||||
|
}
|
||||||
|
|
||||||
class DialogHostState {
|
class DialogHostState {
|
||||||
|
|
||||||
private data class DialogVisualsImpl(
|
private object LoadingDialogVisualsImpl : LoadingDialogVisuals
|
||||||
|
|
||||||
|
private data class PromptDialogVisualsImpl(
|
||||||
|
override val title: String,
|
||||||
|
override val content: String
|
||||||
|
) : PromptDialogVisuals
|
||||||
|
|
||||||
|
private data class ConfirmDialogVisualsImpl(
|
||||||
override val title: String,
|
override val title: String,
|
||||||
override val content: String,
|
override val content: String,
|
||||||
override val confirm: String?,
|
override val confirm: String?,
|
||||||
override val dismiss: String?
|
override val dismiss: String?
|
||||||
) : DialogVisuals
|
) : ConfirmDialogVisuals
|
||||||
|
|
||||||
private data class DialogDataImpl(
|
private data class LoadingDialogDataImpl(
|
||||||
override val visuals: DialogVisuals,
|
override val visuals: LoadingDialogVisuals,
|
||||||
val continuation: CancellableContinuation<DialogResult>
|
private val continuation: CancellableContinuation<Unit>,
|
||||||
) : DialogData {
|
) : LoadingDialogData {
|
||||||
|
override fun dismiss() {
|
||||||
|
if (continuation.isActive) continuation.resume(Unit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private data class PromptDialogDataImpl(
|
||||||
|
override val visuals: PromptDialogVisuals,
|
||||||
|
private val continuation: CancellableContinuation<Unit>,
|
||||||
|
) : PromptDialogData {
|
||||||
|
override fun dismiss() {
|
||||||
|
if (continuation.isActive) continuation.resume(Unit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private data class ConfirmDialogDataImpl(
|
||||||
|
override val visuals: ConfirmDialogVisuals,
|
||||||
|
private val continuation: CancellableContinuation<ConfirmResult>
|
||||||
|
) : ConfirmDialogData {
|
||||||
|
|
||||||
override fun confirm() {
|
override fun confirm() {
|
||||||
if (continuation.isActive) continuation.resume(DialogResult.Confirmed)
|
if (continuation.isActive) continuation.resume(ConfirmResult.Confirmed)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun dismiss() {
|
override fun dismiss() {
|
||||||
if (continuation.isActive) continuation.resume(DialogResult.Dismissed)
|
if (continuation.isActive) continuation.resume(ConfirmResult.Canceled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,16 +116,58 @@ class DialogHostState {
|
|||||||
var currentDialogData by mutableStateOf<DialogData?>(null)
|
var currentDialogData by mutableStateOf<DialogData?>(null)
|
||||||
private set
|
private set
|
||||||
|
|
||||||
suspend fun showDialog(
|
suspend fun showLoading() {
|
||||||
|
try {
|
||||||
|
mutex.withLock {
|
||||||
|
suspendCancellableCoroutine { continuation ->
|
||||||
|
currentDialogData = LoadingDialogDataImpl(
|
||||||
|
visuals = LoadingDialogVisualsImpl,
|
||||||
|
continuation = continuation
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
currentDialogData = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun <R> withLoading(block: suspend () -> R) = coroutineScope {
|
||||||
|
val showLoading = launch {
|
||||||
|
showLoading()
|
||||||
|
}
|
||||||
|
|
||||||
|
val result = block()
|
||||||
|
|
||||||
|
showLoading.cancel()
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun showPrompt(title: String, content: String) {
|
||||||
|
try {
|
||||||
|
mutex.withLock {
|
||||||
|
suspendCancellableCoroutine { continuation ->
|
||||||
|
currentDialogData = PromptDialogDataImpl(
|
||||||
|
visuals = PromptDialogVisualsImpl(title, content),
|
||||||
|
continuation = continuation
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
currentDialogData = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun showConfirm(
|
||||||
title: String,
|
title: String,
|
||||||
content: String,
|
content: String,
|
||||||
confirm: String? = null,
|
confirm: String? = null,
|
||||||
dismiss: String? = null
|
dismiss: String? = null
|
||||||
): DialogResult = mutex.withLock {
|
): ConfirmResult = mutex.withLock {
|
||||||
try {
|
try {
|
||||||
return@withLock suspendCancellableCoroutine { continuation ->
|
return@withLock suspendCancellableCoroutine { continuation ->
|
||||||
currentDialogData = DialogDataImpl(
|
currentDialogData = ConfirmDialogDataImpl(
|
||||||
visuals = DialogVisualsImpl(title, content, confirm, dismiss),
|
visuals = ConfirmDialogVisualsImpl(title, content, confirm, dismiss),
|
||||||
continuation = continuation
|
continuation = continuation
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -85,82 +184,85 @@ fun rememberDialogHostState(): DialogHostState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
private inline fun <reified T : DialogData> DialogData?.tryInto(): T? {
|
||||||
fun BaseDialog(
|
return when (this) {
|
||||||
state: DialogHostState = LocalDialogHost.current,
|
is T -> this
|
||||||
title: @Composable (String) -> Unit,
|
else -> null
|
||||||
confirmButton: @Composable (String?, () -> Unit) -> Unit,
|
}
|
||||||
dismissButton: @Composable (String?, () -> Unit) -> Unit,
|
|
||||||
content: @Composable (String) -> Unit = { Text(text = it) },
|
|
||||||
) {
|
|
||||||
val currentDialogData = state.currentDialogData ?: return
|
|
||||||
val visuals = currentDialogData.visuals
|
|
||||||
AlertDialog(
|
|
||||||
onDismissRequest = {
|
|
||||||
currentDialogData.dismiss()
|
|
||||||
},
|
|
||||||
title = {
|
|
||||||
title(visuals.title)
|
|
||||||
},
|
|
||||||
text = {
|
|
||||||
content(visuals.content)
|
|
||||||
},
|
|
||||||
confirmButton = {
|
|
||||||
confirmButton(visuals.confirm, currentDialogData::confirm)
|
|
||||||
},
|
|
||||||
dismissButton = {
|
|
||||||
dismissButton(visuals.dismiss, currentDialogData::dismiss)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SimpleDialog(
|
fun LoadingDialog(
|
||||||
state: DialogHostState = LocalDialogHost.current,
|
state: DialogHostState = LocalDialogHost.current,
|
||||||
content: @Composable (String) -> Unit
|
|
||||||
) {
|
) {
|
||||||
BaseDialog(
|
state.currentDialogData.tryInto<LoadingDialogData>() ?: return
|
||||||
state = state,
|
val dialogProperties = remember {
|
||||||
|
DialogProperties(dismissOnClickOutside = false, dismissOnBackPress = false)
|
||||||
|
}
|
||||||
|
Dialog(onDismissRequest = {}, properties = dialogProperties) {
|
||||||
|
Surface(
|
||||||
|
modifier = Modifier
|
||||||
|
.size(100.dp),
|
||||||
|
shape = RoundedCornerShape(8.dp)
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
contentAlignment = Alignment.Center,
|
||||||
|
) {
|
||||||
|
CircularProgressIndicator()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun PromptDialog(
|
||||||
|
state: DialogHostState = LocalDialogHost.current,
|
||||||
|
) {
|
||||||
|
val promptDialogData = state.currentDialogData.tryInto<PromptDialogData>() ?: return
|
||||||
|
|
||||||
|
val visuals = promptDialogData.visuals
|
||||||
|
AlertDialog(
|
||||||
|
onDismissRequest = {
|
||||||
|
promptDialogData.dismiss()
|
||||||
|
},
|
||||||
title = {
|
title = {
|
||||||
Text(text = it)
|
Text(text = visuals.title)
|
||||||
},
|
},
|
||||||
confirmButton = { text, confirm ->
|
text = {
|
||||||
text?.let {
|
Text(text = visuals.content)
|
||||||
TextButton(onClick = confirm) {
|
},
|
||||||
Text(text = it)
|
confirmButton = {
|
||||||
}
|
TextButton(onClick = { promptDialogData.dismiss() }) {
|
||||||
|
Text(text = stringResource(id = android.R.string.ok))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
dismissButton = { text, dismiss ->
|
dismissButton = null,
|
||||||
text?.let {
|
|
||||||
TextButton(onClick = dismiss) {
|
|
||||||
Text(text = it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
content = content
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ConfirmDialog(state: DialogHostState = LocalDialogHost.current) {
|
fun ConfirmDialog(state: DialogHostState = LocalDialogHost.current) {
|
||||||
BaseDialog(
|
val confirmDialogData = state.currentDialogData.tryInto<ConfirmDialogData>() ?: return
|
||||||
state = state,
|
|
||||||
title = {
|
val visuals = confirmDialogData.visuals
|
||||||
Text(text = it)
|
AlertDialog(
|
||||||
|
onDismissRequest = {
|
||||||
|
confirmDialogData.dismiss()
|
||||||
},
|
},
|
||||||
confirmButton = { text, confirm ->
|
title = {
|
||||||
text?.let {
|
Text(text = visuals.title)
|
||||||
TextButton(onClick = confirm) {
|
},
|
||||||
Text(text = it)
|
text = {
|
||||||
}
|
Text(text = visuals.content)
|
||||||
|
},
|
||||||
|
confirmButton = {
|
||||||
|
TextButton(onClick = { confirmDialogData.dismiss() }) {
|
||||||
|
Text(text = visuals.confirm ?: stringResource(id = android.R.string.ok))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
dismissButton = { text, dismiss ->
|
dismissButton = {
|
||||||
text?.let {
|
TextButton(onClick = { confirmDialogData.dismiss() }) {
|
||||||
TextButton(onClick = dismiss) {
|
Text(text = visuals.dismiss ?: stringResource(id = android.R.string.cancel))
|
||||||
Text(text = it)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ import kotlinx.coroutines.launch
|
|||||||
import me.weishu.kernelsu.Natives
|
import me.weishu.kernelsu.Natives
|
||||||
import me.weishu.kernelsu.R
|
import me.weishu.kernelsu.R
|
||||||
import me.weishu.kernelsu.ui.component.ConfirmDialog
|
import me.weishu.kernelsu.ui.component.ConfirmDialog
|
||||||
import me.weishu.kernelsu.ui.component.DialogResult
|
import me.weishu.kernelsu.ui.component.ConfirmResult
|
||||||
import me.weishu.kernelsu.ui.screen.destinations.InstallScreenDestination
|
import me.weishu.kernelsu.ui.screen.destinations.InstallScreenDestination
|
||||||
import me.weishu.kernelsu.ui.util.*
|
import me.weishu.kernelsu.ui.util.*
|
||||||
import me.weishu.kernelsu.ui.viewmodel.ModuleViewModel
|
import me.weishu.kernelsu.ui.viewmodel.ModuleViewModel
|
||||||
@@ -143,13 +143,13 @@ private fun ModuleList(viewModel: ModuleViewModel, modifier: Modifier = Modifier
|
|||||||
val snackBarHost = LocalSnackbarHost.current
|
val snackBarHost = LocalSnackbarHost.current
|
||||||
|
|
||||||
suspend fun onModuleUninstall(module: ModuleViewModel.ModuleInfo) {
|
suspend fun onModuleUninstall(module: ModuleViewModel.ModuleInfo) {
|
||||||
val dialogResult = dialogHost.showDialog(
|
val confirmResult = dialogHost.showConfirm(
|
||||||
moduleStr,
|
moduleStr,
|
||||||
content = moduleUninstallConfirm.format(module.name),
|
content = moduleUninstallConfirm.format(module.name),
|
||||||
confirm = uninstall,
|
confirm = uninstall,
|
||||||
dismiss = cancel
|
dismiss = cancel
|
||||||
)
|
)
|
||||||
if (dialogResult != DialogResult.Confirmed) {
|
if (confirmResult != ConfirmResult.Confirmed) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,21 +2,14 @@ package me.weishu.kernelsu.ui.screen
|
|||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import androidx.compose.foundation.background
|
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.ArrowBack
|
import androidx.compose.material.icons.filled.ArrowBack
|
||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color.Companion.White
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.compose.ui.window.Dialog
|
|
||||||
import androidx.compose.ui.window.DialogProperties
|
|
||||||
import androidx.core.content.FileProvider
|
import androidx.core.content.FileProvider
|
||||||
import com.alorma.compose.settings.ui.*
|
import com.alorma.compose.settings.ui.*
|
||||||
import com.ramcosta.composedestinations.annotation.Destination
|
import com.ramcosta.composedestinations.annotation.Destination
|
||||||
@@ -27,6 +20,7 @@ import kotlinx.coroutines.withContext
|
|||||||
import me.weishu.kernelsu.BuildConfig
|
import me.weishu.kernelsu.BuildConfig
|
||||||
import me.weishu.kernelsu.R
|
import me.weishu.kernelsu.R
|
||||||
import me.weishu.kernelsu.ui.component.AboutDialog
|
import me.weishu.kernelsu.ui.component.AboutDialog
|
||||||
|
import me.weishu.kernelsu.ui.component.LoadingDialog
|
||||||
import me.weishu.kernelsu.ui.util.LocalDialogHost
|
import me.weishu.kernelsu.ui.util.LocalDialogHost
|
||||||
import me.weishu.kernelsu.ui.util.getBugreportFile
|
import me.weishu.kernelsu.ui.util.getBugreportFile
|
||||||
|
|
||||||
@@ -46,13 +40,11 @@ fun SettingScreen(navigator: DestinationsNavigator) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
|
LoadingDialog()
|
||||||
|
|
||||||
val showAboutDialog = remember { mutableStateOf(false) }
|
val showAboutDialog = remember { mutableStateOf(false) }
|
||||||
AboutDialog(showAboutDialog)
|
AboutDialog(showAboutDialog)
|
||||||
|
|
||||||
var showLoadingDialog by remember { mutableStateOf(false) }
|
|
||||||
LoadingDialog(showLoadingDialog)
|
|
||||||
|
|
||||||
Column(modifier = Modifier.padding(paddingValues)) {
|
Column(modifier = Modifier.padding(paddingValues)) {
|
||||||
|
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
@@ -64,14 +56,12 @@ fun SettingScreen(navigator: DestinationsNavigator) {
|
|||||||
},
|
},
|
||||||
onClick = {
|
onClick = {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
showLoadingDialog = true
|
val bugreport = dialogHost.withLoading {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
val bugreport = withContext(Dispatchers.IO) {
|
getBugreportFile(context)
|
||||||
getBugreportFile(context)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showLoadingDialog = false
|
|
||||||
|
|
||||||
val uri: Uri =
|
val uri: Uri =
|
||||||
FileProvider.getUriForFile(
|
FileProvider.getUriForFile(
|
||||||
context,
|
context,
|
||||||
@@ -119,24 +109,3 @@ private fun TopBar(onBack: () -> Unit = {}) {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun LoadingDialog(showLoadingDialog: Boolean) {
|
|
||||||
if (!showLoadingDialog) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
Dialog(
|
|
||||||
onDismissRequest = { },
|
|
||||||
DialogProperties(dismissOnBackPress = false, dismissOnClickOutside = false)
|
|
||||||
) {
|
|
||||||
Box(
|
|
||||||
contentAlignment = Alignment.Center,
|
|
||||||
modifier = Modifier
|
|
||||||
.size(100.dp)
|
|
||||||
.background(White, shape = RoundedCornerShape(8.dp))
|
|
||||||
) {
|
|
||||||
CircularProgressIndicator()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -25,7 +25,7 @@ import kotlinx.coroutines.launch
|
|||||||
import me.weishu.kernelsu.Natives
|
import me.weishu.kernelsu.Natives
|
||||||
import me.weishu.kernelsu.R
|
import me.weishu.kernelsu.R
|
||||||
import me.weishu.kernelsu.ui.component.ConfirmDialog
|
import me.weishu.kernelsu.ui.component.ConfirmDialog
|
||||||
import me.weishu.kernelsu.ui.component.DialogResult
|
import me.weishu.kernelsu.ui.component.ConfirmResult
|
||||||
import me.weishu.kernelsu.ui.component.SearchAppBar
|
import me.weishu.kernelsu.ui.component.SearchAppBar
|
||||||
import me.weishu.kernelsu.ui.util.LocalDialogHost
|
import me.weishu.kernelsu.ui.util.LocalDialogHost
|
||||||
import me.weishu.kernelsu.ui.util.LocalSnackbarHost
|
import me.weishu.kernelsu.ui.util.LocalSnackbarHost
|
||||||
@@ -119,13 +119,13 @@ fun SuperUserScreen() {
|
|||||||
AppItem(app, isChecked) { checked ->
|
AppItem(app, isChecked) { checked ->
|
||||||
scope.launch {
|
scope.launch {
|
||||||
if (checked) {
|
if (checked) {
|
||||||
val dialogResult = dialogHost.showDialog(
|
val confirmResult = dialogHost.showConfirm(
|
||||||
app.label,
|
app.label,
|
||||||
content = content,
|
content = content,
|
||||||
confirm = confirm,
|
confirm = confirm,
|
||||||
dismiss = cancel
|
dismiss = cancel
|
||||||
)
|
)
|
||||||
if (dialogResult != DialogResult.Confirmed) {
|
if (confirmResult != ConfirmResult.Confirmed) {
|
||||||
return@launch
|
return@launch
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user