|
|
@@ -0,0 +1,234 @@
|
|
|
+package com.hzliuzhi.applet.container.ui
|
|
|
+
|
|
|
+import android.content.Intent
|
|
|
+import android.provider.Settings
|
|
|
+import android.util.Patterns
|
|
|
+import android.widget.Toast
|
|
|
+import androidx.compose.foundation.clickable
|
|
|
+import androidx.compose.foundation.layout.Arrangement
|
|
|
+import androidx.compose.foundation.layout.Box
|
|
|
+import androidx.compose.foundation.layout.Column
|
|
|
+import androidx.compose.foundation.layout.Row
|
|
|
+import androidx.compose.foundation.layout.Spacer
|
|
|
+import androidx.compose.foundation.layout.fillMaxSize
|
|
|
+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.text.KeyboardActions
|
|
|
+import androidx.compose.foundation.text.KeyboardOptions
|
|
|
+import androidx.compose.material.icons.Icons
|
|
|
+import androidx.compose.material.icons.automirrored.filled.Send
|
|
|
+import androidx.compose.material.icons.filled.Info
|
|
|
+import androidx.compose.material.icons.filled.QrCode
|
|
|
+import androidx.compose.material3.Card
|
|
|
+import androidx.compose.material3.Icon
|
|
|
+import androidx.compose.material3.MaterialTheme
|
|
|
+import androidx.compose.material3.OutlinedTextField
|
|
|
+import androidx.compose.material3.Surface
|
|
|
+import androidx.compose.material3.Switch
|
|
|
+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.Alignment
|
|
|
+import androidx.compose.ui.Modifier
|
|
|
+import androidx.compose.ui.graphics.Color
|
|
|
+import androidx.compose.ui.platform.LocalContext
|
|
|
+import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
|
|
+import androidx.compose.ui.text.input.ImeAction
|
|
|
+import androidx.compose.ui.text.input.KeyboardType
|
|
|
+import androidx.compose.ui.text.style.TextDecoration
|
|
|
+import androidx.compose.ui.unit.dp
|
|
|
+import androidx.core.net.toUri
|
|
|
+import com.hzliuzhi.applet.core.store.SettingStore
|
|
|
+
|
|
|
+
|
|
|
+@Composable
|
|
|
+fun LauncherScreen(
|
|
|
+ modifier: Modifier = Modifier,
|
|
|
+ start: (String) -> String?,
|
|
|
+ scan: () -> Unit = {},
|
|
|
+) {
|
|
|
+ val context = LocalContext.current
|
|
|
+ var text by remember { mutableStateOf("https://www.bing.com/") }
|
|
|
+ var storeEnabled by remember { mutableStateOf(true) }
|
|
|
+
|
|
|
+ Column(
|
|
|
+ modifier = modifier
|
|
|
+ .fillMaxSize()
|
|
|
+ .padding(24.dp),
|
|
|
+ verticalArrangement = Arrangement.Center
|
|
|
+ ) {
|
|
|
+ LauncherInputField(
|
|
|
+ value = text,
|
|
|
+ onValueChange = { text = it },
|
|
|
+ onDone = {
|
|
|
+ start(text)?.also {
|
|
|
+ SettingStore.getInstance(context).screen = if (storeEnabled) it else null
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onScan = scan
|
|
|
+ )
|
|
|
+ Spacer(modifier = Modifier.height(24.dp))
|
|
|
+ StorageCard(
|
|
|
+ enabled = storeEnabled,
|
|
|
+ enabledChange = { storeEnabled = it }
|
|
|
+ )
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+@Composable
|
|
|
+fun LauncherInputField(
|
|
|
+ value: String,
|
|
|
+ onValueChange: (String) -> Unit,
|
|
|
+ onDone: () -> Unit,
|
|
|
+ onScan: () -> Unit,
|
|
|
+ modifier: Modifier = Modifier,
|
|
|
+) {
|
|
|
+ val context = LocalContext.current
|
|
|
+ val isUrl = remember(value) { Patterns.WEB_URL.matcher(value).matches() }
|
|
|
+
|
|
|
+ val keyboardController = LocalSoftwareKeyboardController.current
|
|
|
+
|
|
|
+ fun done() {
|
|
|
+ if (isUrl) {
|
|
|
+ keyboardController?.hide()
|
|
|
+ onDone()
|
|
|
+ } else Toast.makeText(context, "请输入合法的网址", Toast.LENGTH_SHORT).show()
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ OutlinedTextField(
|
|
|
+ value = value,
|
|
|
+ onValueChange = onValueChange,
|
|
|
+ label = { Text("请输入URL") },
|
|
|
+ singleLine = true,
|
|
|
+ isError = value.isNotBlank() && !isUrl,
|
|
|
+ modifier = modifier.fillMaxWidth(),
|
|
|
+ keyboardOptions = KeyboardOptions(
|
|
|
+ keyboardType = KeyboardType.Uri,
|
|
|
+ imeAction = ImeAction.Done
|
|
|
+ ),
|
|
|
+ keyboardActions = KeyboardActions(onDone = { done() }),
|
|
|
+ trailingIcon = {
|
|
|
+ if (value.isBlank()) {
|
|
|
+ Icon(
|
|
|
+ imageVector = Icons.Filled.QrCode,
|
|
|
+ contentDescription = "扫码",
|
|
|
+ modifier = Modifier.clickable {
|
|
|
+ onScan()
|
|
|
+ keyboardController?.hide()
|
|
|
+ }
|
|
|
+ )
|
|
|
+ } else {
|
|
|
+ Icon(
|
|
|
+ imageVector = Icons.AutoMirrored.Filled.Send,
|
|
|
+ contentDescription = "完成",
|
|
|
+ modifier = Modifier.clickable { done() }
|
|
|
+ )
|
|
|
+ }
|
|
|
+ }
|
|
|
+ )
|
|
|
+}
|
|
|
+
|
|
|
+@Composable
|
|
|
+fun StorageCard(
|
|
|
+ enabled: Boolean,
|
|
|
+ enabledChange: (Boolean) -> Unit,
|
|
|
+) {
|
|
|
+ val context = LocalContext.current
|
|
|
+
|
|
|
+ val appName = runCatching {
|
|
|
+ val info = context.applicationInfo
|
|
|
+ info.labelRes.takeIf { it != 0 }?.let { context.getString(it) } ?: info.nonLocalizedLabel?.toString()
|
|
|
+ }.getOrNull() ?: "本App"
|
|
|
+
|
|
|
+ Card(
|
|
|
+ modifier = Modifier.fillMaxWidth(),
|
|
|
+ shape = MaterialTheme.shapes.medium,
|
|
|
+ ) {
|
|
|
+ Column(
|
|
|
+ modifier = Modifier.padding(start = 12.dp, end = 12.dp)
|
|
|
+ ) {
|
|
|
+ // 头部:标题+开关
|
|
|
+ Row(
|
|
|
+ modifier = Modifier.fillMaxWidth(),
|
|
|
+ verticalAlignment = Alignment.CenterVertically
|
|
|
+ ) {
|
|
|
+ Text(
|
|
|
+ text = "存储数据",
|
|
|
+ style = MaterialTheme.typography.titleMedium,
|
|
|
+ modifier = Modifier.weight(1f)
|
|
|
+ )
|
|
|
+ Switch(
|
|
|
+ checked = enabled,
|
|
|
+ onCheckedChange = enabledChange
|
|
|
+ )
|
|
|
+ }
|
|
|
+ if (enabled) {
|
|
|
+ Spacer(modifier = Modifier.height(8.dp))
|
|
|
+ Row(verticalAlignment = Alignment.CenterVertically) {
|
|
|
+ Icon(
|
|
|
+ imageVector = Icons.Default.Info,
|
|
|
+ contentDescription = null,
|
|
|
+ tint = MaterialTheme.colorScheme.secondary
|
|
|
+ )
|
|
|
+ Spacer(modifier = Modifier.width(8.dp))
|
|
|
+ Text(
|
|
|
+ text = "如需清除缓存,请在",
|
|
|
+ style = MaterialTheme.typography.bodyMedium,
|
|
|
+ color = MaterialTheme.colorScheme.secondary
|
|
|
+ )
|
|
|
+ Text(
|
|
|
+ text = "设置中操作",
|
|
|
+ style = MaterialTheme.typography.bodyMedium.copy(color = Color(0xFF1976D2), textDecoration = TextDecoration.Underline),
|
|
|
+ modifier = Modifier
|
|
|
+ .clickable {
|
|
|
+ val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
|
|
|
+ data = ("package:" + context.packageName).toUri()
|
|
|
+ }
|
|
|
+ context.startActivity(intent)
|
|
|
+ }
|
|
|
+ )
|
|
|
+ }
|
|
|
+ Spacer(modifier = Modifier.height(12.dp))
|
|
|
+ Text(
|
|
|
+ text = "清除缓存步骤:",
|
|
|
+ style = MaterialTheme.typography.bodyMedium,
|
|
|
+ color = MaterialTheme.colorScheme.primary
|
|
|
+ )
|
|
|
+ Spacer(modifier = Modifier.height(8.dp))
|
|
|
+ Column {
|
|
|
+ val steps = listOf(
|
|
|
+ "打开系统设置",
|
|
|
+ "找到应用管理",
|
|
|
+ "选择$appName",
|
|
|
+ "进入存储与缓存",
|
|
|
+ "点击清除缓存"
|
|
|
+ )
|
|
|
+ steps.forEachIndexed { idx, step ->
|
|
|
+ Row(verticalAlignment = Alignment.CenterVertically) {
|
|
|
+ Surface(
|
|
|
+ shape = MaterialTheme.shapes.small,
|
|
|
+ color = MaterialTheme.colorScheme.primary.copy(alpha = 0.1f),
|
|
|
+ modifier = Modifier.size(24.dp)
|
|
|
+ ) {
|
|
|
+ Box(contentAlignment = Alignment.Center) {
|
|
|
+ Text("${idx + 1}", style = MaterialTheme.typography.labelMedium)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Spacer(modifier = Modifier.width(8.dp))
|
|
|
+ Text(step, style = MaterialTheme.typography.bodySmall)
|
|
|
+ }
|
|
|
+ if (idx < steps.lastIndex) Spacer(modifier = Modifier.height(6.dp))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Spacer(modifier = Modifier.height(8.dp))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|