Code clean
This commit is contained in:
1 parent
f6ea2df5a0
commit
4949528eeb
34 files changed
+172
-79
No files matched your search
@@ -140,7 +140,9 @@ private fun SearchInputField(
|
||||
)
|
||||
),
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search),
|
||||
modifier = Modifier.weight(1f).focusRequester(focusRequester)
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.focusRequester(focusRequester)
|
||||
)
|
||||
if (query.isNotEmpty()) {
|
||||
IconButton(onClick = { onQueryChange("") }) {
|
||||
@@ -176,6 +178,7 @@ fun AppListItem(
|
||||
contentScale = ContentScale.Fit
|
||||
)
|
||||
}
|
||||
|
||||
is Int -> {
|
||||
Image(
|
||||
painter = painterResource(id = icon),
|
||||
@@ -184,6 +187,7 @@ fun AppListItem(
|
||||
contentScale = ContentScale.Fit
|
||||
)
|
||||
}
|
||||
|
||||
is Drawable -> {
|
||||
val bitmap = remember(icon) { createBitmapFromDrawable(icon) }
|
||||
Image(
|
||||
@@ -193,6 +197,7 @@ fun AppListItem(
|
||||
contentScale = ContentScale.Fit
|
||||
)
|
||||
}
|
||||
|
||||
else -> {
|
||||
Box(modifier = Modifier.size(40.dp))
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ import androidx.compose.ui.graphics.asImageBitmap
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.input.VisualTransformation
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.v2ray.ang.R
|
||||
|
||||
@Composable
|
||||
fun ConfirmDialog(
|
||||
@@ -175,7 +174,9 @@ fun SelectListDialog(
|
||||
text = option,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
modifier = if (!showRadio)
|
||||
Modifier.fillMaxWidth().padding(vertical = 8.dp, horizontal = 4.dp)
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 8.dp, horizontal = 4.dp)
|
||||
else Modifier
|
||||
)
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.input.VisualTransformation
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.v2ray.ang.R
|
||||
|
||||
@Composable
|
||||
fun PreferenceGroupHeader(title: String, modifier: Modifier = Modifier) {
|
||||
@@ -113,7 +112,9 @@ fun SettingsEditItem(
|
||||
title = title,
|
||||
description = description,
|
||||
enabled = enabled,
|
||||
onClick = if (enabled) { { showDialog = true } } else null,
|
||||
onClick = if (enabled) {
|
||||
{ showDialog = true }
|
||||
} else null,
|
||||
modifier = modifier
|
||||
)
|
||||
|
||||
@@ -157,7 +158,9 @@ fun SettingsListItem(
|
||||
title = title,
|
||||
description = summary.ifEmpty { null },
|
||||
enabled = enabled,
|
||||
onClick = if (enabled) { { showDialog = true } } else null,
|
||||
onClick = if (enabled) {
|
||||
{ showDialog = true }
|
||||
} else null,
|
||||
modifier = modifier
|
||||
)
|
||||
|
||||
@@ -209,7 +212,9 @@ fun SettingsSwitchItem(
|
||||
title = title,
|
||||
description = summary,
|
||||
enabled = enabled,
|
||||
onClick = if (enabled) { { onCheckedChange(!checked) } } else null,
|
||||
onClick = if (enabled) {
|
||||
{ onCheckedChange(!checked) }
|
||||
} else null,
|
||||
modifier = modifier,
|
||||
trailing = {
|
||||
Switch(
|
||||
|
||||
@@ -6,8 +6,8 @@ import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.BoxWithConstraints
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
@@ -92,7 +92,7 @@ class AppSnackbarController(
|
||||
val hostState: SnackbarHostState,
|
||||
private val scope: CoroutineScope,
|
||||
) {
|
||||
fun show(message: CharSequence, type: ToastType = ToastType.NORMAL, long: Boolean = false, ) {
|
||||
fun show(message: CharSequence, type: ToastType = ToastType.NORMAL, long: Boolean = false) {
|
||||
scope.launch {
|
||||
hostState.currentSnackbarData?.dismiss()
|
||||
hostState.showSnackbar(
|
||||
@@ -104,30 +104,30 @@ class AppSnackbarController(
|
||||
}
|
||||
}
|
||||
|
||||
fun showInfo(context: Context, @StringRes messageRes: Int, long: Boolean = false, ) {
|
||||
fun showInfo(context: Context, @StringRes messageRes: Int, long: Boolean = false) {
|
||||
show(context.getString(messageRes), ToastType.NORMAL, long)
|
||||
}
|
||||
|
||||
|
||||
fun showInfo(message: CharSequence, long: Boolean = false, ) {
|
||||
fun showInfo(message: CharSequence, long: Boolean = false) {
|
||||
show(message, ToastType.NORMAL, long)
|
||||
}
|
||||
|
||||
|
||||
fun showSuccess(context: Context, @StringRes messageRes: Int, long: Boolean = false, ) {
|
||||
fun showSuccess(context: Context, @StringRes messageRes: Int, long: Boolean = false) {
|
||||
show(context.getString(messageRes), ToastType.SUCCESS, long)
|
||||
}
|
||||
|
||||
|
||||
fun showSuccess(message: CharSequence, long: Boolean = false, ) {
|
||||
fun showSuccess(message: CharSequence, long: Boolean = false) {
|
||||
show(message, ToastType.SUCCESS, long)
|
||||
}
|
||||
|
||||
fun showError(context: Context, @StringRes messageRes: Int, long: Boolean = false, ) {
|
||||
fun showError(context: Context, @StringRes messageRes: Int, long: Boolean = false) {
|
||||
show(context.getString(messageRes), ToastType.ERROR, long)
|
||||
}
|
||||
|
||||
fun showError(message: CharSequence, long: Boolean = false, ) {
|
||||
fun showError(message: CharSequence, long: Boolean = false) {
|
||||
show(message, ToastType.ERROR, long)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -915,7 +915,7 @@ object CoreConfigManager {
|
||||
return hosts
|
||||
}
|
||||
|
||||
private fun buildDnsCnModeFromRoutingRules(configContext: CoreConfigContext, servers: ArrayList<Any>, domesticDns: List<String>, ): List<String> {
|
||||
private fun buildDnsCnModeFromRoutingRules(configContext: CoreConfigContext, servers: ArrayList<Any>, domesticDns: List<String>): List<String> {
|
||||
val cnRegionFilter = { domain: String ->
|
||||
domain.startsWith("geosite:") && (domain.endsWith("-cn") || domain.endsWith("@cn"))
|
||||
|| domain == AppConfig.GEOSITE_CN
|
||||
@@ -981,6 +981,7 @@ object CoreConfigManager {
|
||||
domesticDnsTags.add(tag)
|
||||
}
|
||||
}
|
||||
|
||||
AppConfig.TAG_BLOCKED -> Unit
|
||||
else -> {
|
||||
servers.add(
|
||||
|
||||
@@ -61,6 +61,7 @@ data class V2rayNShareItem(
|
||||
val Filter: String?,
|
||||
val MultipleLoad: Int?,
|
||||
)
|
||||
|
||||
data class V2rayNTransportExtraShareItem(
|
||||
val RawHeaderType: String?,
|
||||
val Host: String?,
|
||||
|
||||
@@ -497,7 +497,8 @@ object AngConfigManager {
|
||||
config.description = generateDescription(config)
|
||||
|
||||
if (str.startsWith(AppConfig.V2RAYNFMTS, ignoreCase = true)
|
||||
&& config.policyGroupSubscriptionId == "self") {
|
||||
&& config.policyGroupSubscriptionId == "self"
|
||||
) {
|
||||
config.policyGroupSubscriptionId = subid
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ object SettingsChangeManager {
|
||||
fun makeRestartService() {
|
||||
restartService.set(true)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Atomically consumes the restart flag.
|
||||
* @return true if a restart was requested, false otherwise.
|
||||
|
||||
@@ -114,7 +114,9 @@ fun AboutScreen(onBackClick: () -> Unit) {
|
||||
loadUrl("file:///android_asset/open_source_licenses.html")
|
||||
}
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth().heightIn(min = 300.dp)
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.heightIn(min = 300.dp)
|
||||
)
|
||||
},
|
||||
confirmButton = {
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.v2ray.ang.ui
|
||||
import android.content.Intent
|
||||
import android.graphics.BitmapFactory
|
||||
import android.os.Bundle
|
||||
import android.util.Size as TargetSize
|
||||
import androidx.camera.compose.CameraXViewfinder
|
||||
import androidx.camera.core.Camera
|
||||
import androidx.camera.core.CameraControl
|
||||
@@ -72,6 +71,7 @@ import com.v2ray.ang.util.LogUtil
|
||||
import com.v2ray.ang.util.QRCodeDecoder
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import android.util.Size as TargetSize
|
||||
|
||||
private val qrReader = MultiFormatReader()
|
||||
|
||||
|
||||
@@ -24,8 +24,8 @@ import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
|
||||
@@ -14,7 +14,6 @@ import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.text.Collator
|
||||
import kotlin.collections.plus
|
||||
|
||||
/**
|
||||
* ViewModel for AppPicker screen.
|
||||
|
||||
@@ -168,7 +168,7 @@ fun LogcatScreen(
|
||||
IconButton(onClick = {
|
||||
val all = viewModel.filteredLogs.value.joinToString("\n")
|
||||
Utils.setClipboard(context, all)
|
||||
snackbar.showInfo(context,R.string.toast_success)
|
||||
snackbar.showInfo(context, R.string.toast_success)
|
||||
}) {
|
||||
Icon(
|
||||
painterResource(R.drawable.ic_copy),
|
||||
|
||||
@@ -26,14 +26,11 @@ import com.v2ray.ang.handler.SettingsChangeManager
|
||||
import com.v2ray.ang.handler.SettingsManager
|
||||
import com.v2ray.ang.ui.AboutActivity
|
||||
import com.v2ray.ang.ui.backup.BackupActivity
|
||||
import com.v2ray.ang.ui.checkupdate.CheckUpdateActivity
|
||||
import com.v2ray.ang.ui.base.HelperBaseComponentActivity
|
||||
import com.v2ray.ang.ui.checkupdate.CheckUpdateActivity
|
||||
import com.v2ray.ang.ui.logcat.LogcatActivity
|
||||
import com.v2ray.ang.ui.perappproxy.PerAppProxyActivity
|
||||
import com.v2ray.ang.ui.routing.RoutingSettingActivity
|
||||
import com.v2ray.ang.ui.settings.SettingsActivity
|
||||
import com.v2ray.ang.ui.subscription.SubSettingActivity
|
||||
import com.v2ray.ang.ui.userasset.UserAssetActivity
|
||||
import com.v2ray.ang.ui.server.ProfileEditorResult
|
||||
import com.v2ray.ang.ui.server.ServerCustomConfigActivity
|
||||
import com.v2ray.ang.ui.server.ServerGroupActivity
|
||||
@@ -46,6 +43,9 @@ import com.v2ray.ang.ui.server.ServerTrojanActivity
|
||||
import com.v2ray.ang.ui.server.ServerVlessActivity
|
||||
import com.v2ray.ang.ui.server.ServerVmessActivity
|
||||
import com.v2ray.ang.ui.server.ServerWireguardActivity
|
||||
import com.v2ray.ang.ui.settings.SettingsActivity
|
||||
import com.v2ray.ang.ui.subscription.SubSettingActivity
|
||||
import com.v2ray.ang.ui.userasset.UserAssetActivity
|
||||
import com.v2ray.ang.util.LogUtil
|
||||
import com.v2ray.ang.util.Utils
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -65,7 +65,7 @@ class MainActivity : HelperBaseComponentActivity() {
|
||||
|
||||
private val profileEditorLauncher =
|
||||
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
||||
if (result.resultCode != Activity.RESULT_OK) return@registerForActivityResult
|
||||
if (result.resultCode != RESULT_OK) return@registerForActivityResult
|
||||
val data = result.data ?: return@registerForActivityResult
|
||||
val action = data.getStringExtra(ProfileEditorResult.EXTRA_ACTION)
|
||||
?: return@registerForActivityResult
|
||||
@@ -155,6 +155,7 @@ class MainActivity : HelperBaseComponentActivity() {
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
else -> return
|
||||
}
|
||||
settingsActivityLauncher.launch(intent)
|
||||
|
||||
@@ -5,15 +5,15 @@ 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.WindowInsets
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.navigationBars
|
||||
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.windowInsetsPadding
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.navigationBars
|
||||
import androidx.compose.material3.FloatingActionButton
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
|
||||
@@ -57,5 +57,5 @@ sealed interface MainAction {
|
||||
|
||||
data class ImportBatchConfig(val configText: String) : MainAction
|
||||
|
||||
data class LocateHandled(val target: com.v2ray.ang.dto.LocateTarget) : MainAction
|
||||
data class LocateHandled(val target: LocateTarget) : MainAction
|
||||
}
|
||||
@@ -53,9 +53,11 @@ fun MainDrawerContent(onNavigate: (String) -> Unit) {
|
||||
.verticalScrollbar(drawerScrollState)
|
||||
.padding(bottom = 80.dp)
|
||||
) {
|
||||
Surface(modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(160.dp)) {
|
||||
Surface(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(160.dp)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
package com.v2ray.ang.ui.main
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import com.v2ray.ang.R
|
||||
import com.v2ray.ang.compose.QRCodeDialog
|
||||
import com.v2ray.ang.compose.SelectListDialog
|
||||
import com.v2ray.ang.dto.entities.ProfileItem
|
||||
import com.v2ray.ang.enums.EConfigType
|
||||
|
||||
@@ -51,17 +51,21 @@ class MainRepository(
|
||||
AppConfig.MSG_STATE_START_FAILURE -> MainServiceEvent.StateStartFailure(
|
||||
safeIntent.getStringExtra("content").orEmpty()
|
||||
)
|
||||
|
||||
AppConfig.MSG_STATE_STOP_SUCCESS -> MainServiceEvent.StateStopSuccess
|
||||
AppConfig.MSG_MEASURE_DELAY_SUCCESS -> MainServiceEvent.MeasureDelaySuccess(
|
||||
safeIntent.getStringExtra("content").orEmpty()
|
||||
)
|
||||
|
||||
AppConfig.MSG_MEASURE_CONFIG_SUCCESS -> MainServiceEvent.MeasureConfigSuccess
|
||||
AppConfig.MSG_MEASURE_CONFIG_NOTIFY -> MainServiceEvent.MeasureConfigNotify(
|
||||
safeIntent.getStringExtra("content").orEmpty()
|
||||
)
|
||||
|
||||
AppConfig.MSG_MEASURE_CONFIG_FINISH -> MainServiceEvent.MeasureConfigFinish(
|
||||
safeIntent.getStringExtra("content")
|
||||
)
|
||||
|
||||
else -> null
|
||||
}
|
||||
event?.let { _mainServiceEvent.tryEmit(it) }
|
||||
|
||||
@@ -4,10 +4,10 @@ import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.pager.HorizontalPager
|
||||
import androidx.compose.foundation.pager.rememberPagerState
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.foundation.lazy.grid.LazyGridState
|
||||
import androidx.compose.foundation.pager.HorizontalPager
|
||||
import androidx.compose.foundation.pager.rememberPagerState
|
||||
import androidx.compose.material3.DrawerValue
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.ModalNavigationDrawer
|
||||
|
||||
@@ -317,18 +317,36 @@ fun ServerListItem(
|
||||
dragModifier: Modifier = Modifier
|
||||
) {
|
||||
Row(
|
||||
modifier = modifier.fillMaxWidth().height(IntrinsicSize.Min).clickable(onClick = onClick).then(dragModifier)
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.height(IntrinsicSize.Min)
|
||||
.clickable(onClick = onClick)
|
||||
.then(dragModifier)
|
||||
) {
|
||||
Box(Modifier.width(10.dp).fillMaxHeight()) {
|
||||
Box(
|
||||
Modifier
|
||||
.width(10.dp)
|
||||
.fillMaxHeight()
|
||||
) {
|
||||
if (isSelected) {
|
||||
Row {
|
||||
Spacer(Modifier.width(6.dp))
|
||||
Box(Modifier.width(4.dp).fillMaxHeight().padding(vertical = 10.dp).background(MaterialTheme.colorScheme.primary))
|
||||
Box(
|
||||
Modifier
|
||||
.width(4.dp)
|
||||
.fillMaxHeight()
|
||||
.padding(vertical = 10.dp)
|
||||
.background(MaterialTheme.colorScheme.primary)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column(Modifier.weight(1f).padding(start = 8.dp, end = 12.dp, top = 8.dp, bottom = 8.dp)) {
|
||||
Column(
|
||||
Modifier
|
||||
.weight(1f)
|
||||
.padding(start = 8.dp, end = 12.dp, top = 8.dp, bottom = 8.dp)
|
||||
) {
|
||||
Row(Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
|
||||
Text(remarks, Modifier.weight(1f), style = MaterialTheme.typography.bodyLarge.copy(lineBreak = LineBreak.Paragraph), maxLines = 2, overflow = TextOverflow.Ellipsis)
|
||||
if (doubleColumnDisplay) {
|
||||
@@ -344,7 +362,12 @@ fun ServerListItem(
|
||||
Spacer(modifier = Modifier.height(6.dp))
|
||||
Row(Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
|
||||
if (subscriptionRemarks.isNotBlank()) {
|
||||
Box(Modifier.size(24.dp).clip(CircleShape).background(MaterialTheme.colorScheme.primary.copy(alpha = 0.2f)), Alignment.Center) {
|
||||
Box(
|
||||
Modifier
|
||||
.size(24.dp)
|
||||
.clip(CircleShape)
|
||||
.background(MaterialTheme.colorScheme.primary.copy(alpha = 0.2f)), Alignment.Center
|
||||
) {
|
||||
Text(subscriptionRemarks.take(1).uppercase(), fontSize = 11.sp, fontWeight = FontWeight.Bold, color = MaterialTheme.colorScheme.primary)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.v2ray.ang.ui.main
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.asPaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.navigationBars
|
||||
import androidx.compose.foundation.layout.statusBars
|
||||
|
||||
@@ -181,9 +181,11 @@ class MainViewModel(
|
||||
val bitmap = dataSource.share2QRCode(action.guid)
|
||||
_uiState.update { it.copy(shareQRCodeBitmap = bitmap) }
|
||||
}
|
||||
|
||||
MainAction.DismissQRCodeDialog -> {
|
||||
_uiState.update { it.copy(shareQRCodeBitmap = null) }
|
||||
}
|
||||
|
||||
MainAction.ToggleService,
|
||||
MainAction.TestCurrentServer,
|
||||
MainAction.ImportQRcode,
|
||||
|
||||
@@ -31,8 +31,8 @@ import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.scale
|
||||
@@ -192,7 +192,11 @@ fun PerAppProxyScreen(
|
||||
)
|
||||
}
|
||||
) { innerPadding ->
|
||||
Column(modifier = Modifier.fillMaxSize().padding(innerPadding)) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(innerPadding)
|
||||
) {
|
||||
Surface(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
color = MaterialTheme.colorScheme.surface
|
||||
|
||||
@@ -4,12 +4,12 @@ import android.os.Bundle
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.consumeWindowInsets
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.imePadding
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Icon
|
||||
|
||||
@@ -3,8 +3,8 @@ package com.v2ray.ang.ui.server
|
||||
import android.os.Bundle
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.consumeWindowInsets
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.imePadding
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
@@ -19,8 +19,8 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
@@ -375,13 +375,21 @@ fun ServerScreen(
|
||||
if (configType != EConfigType.HYSTERIA2) item { FormTextField(stringResource(R.string.server_lab_port), port, { port = it }, keyboardType = KeyboardType.Number) }
|
||||
when {
|
||||
isVmess || isTrojan || isShadowsocks || isHysteria2 -> item {
|
||||
FormTextField(stringResource(when { isTrojan||isShadowsocks||isHysteria2 -> R.string.server_lab_id3 else -> R.string.server_lab_id }), password, { password = it })
|
||||
FormTextField(
|
||||
stringResource(
|
||||
when {
|
||||
isTrojan || isShadowsocks || isHysteria2 -> R.string.server_lab_id3
|
||||
else -> R.string.server_lab_id
|
||||
}
|
||||
), password, { password = it })
|
||||
}
|
||||
|
||||
isVless -> {
|
||||
item { FormTextField(stringResource(R.string.server_lab_id), password, { password = it }) }
|
||||
item { FormTextField(stringResource(R.string.server_lab_encryption), encryption, { encryption = it }) }
|
||||
item { FormDropdownField(stringResource(R.string.server_lab_flow), flow, flowOptions, { flow = it }) }
|
||||
}
|
||||
|
||||
isSocksOrHttp -> {
|
||||
item { FormTextField(stringResource(R.string.server_lab_security4), username, { username = it }) }
|
||||
item { FormTextField(stringResource(R.string.server_lab_id4), password, { password = it }) }
|
||||
@@ -415,26 +423,40 @@ fun ServerScreen(
|
||||
if (headerOptions.size > 1) {
|
||||
item {
|
||||
FormDropdownField(
|
||||
stringResource(when (network) { NetworkType.GRPC.type -> R.string.server_lab_mode_type; NetworkType.XHTTP.type -> R.string.server_lab_xhttp_mode; else -> R.string.server_lab_head_type }),
|
||||
stringResource(
|
||||
when (network) {
|
||||
NetworkType.GRPC.type -> R.string.server_lab_mode_type; NetworkType.XHTTP.type -> R.string.server_lab_xhttp_mode; else -> R.string.server_lab_head_type
|
||||
}
|
||||
),
|
||||
headerType, headerOptions, { headerType = it }
|
||||
)
|
||||
}
|
||||
}
|
||||
item { FormTextField(stringResource(when (network) {
|
||||
NetworkType.TCP.type, NetworkType.HTTP_UPGRADE.type, NetworkType.XHTTP.type, NetworkType.H2.type -> R.string.server_lab_request_host_http
|
||||
NetworkType.WS.type -> R.string.server_lab_request_host_ws
|
||||
NetworkType.GRPC.type -> R.string.server_lab_request_host_grpc
|
||||
else -> R.string.server_lab_request_host6
|
||||
}), host, { host = it }) }
|
||||
item { FormTextField(stringResource(when (network) {
|
||||
NetworkType.KCP.type -> R.string.server_lab_path_kcp
|
||||
NetworkType.WS.type -> R.string.server_lab_path_ws
|
||||
NetworkType.HTTP_UPGRADE.type -> R.string.server_lab_path_httpupgrade
|
||||
NetworkType.XHTTP.type -> R.string.server_lab_path_xhttp
|
||||
NetworkType.H2.type -> R.string.server_lab_path_h2
|
||||
NetworkType.GRPC.type -> R.string.server_lab_path_grpc
|
||||
else -> R.string.server_lab_path
|
||||
}), path, { path = it }) }
|
||||
item {
|
||||
FormTextField(
|
||||
stringResource(
|
||||
when (network) {
|
||||
NetworkType.TCP.type, NetworkType.HTTP_UPGRADE.type, NetworkType.XHTTP.type, NetworkType.H2.type -> R.string.server_lab_request_host_http
|
||||
NetworkType.WS.type -> R.string.server_lab_request_host_ws
|
||||
NetworkType.GRPC.type -> R.string.server_lab_request_host_grpc
|
||||
else -> R.string.server_lab_request_host6
|
||||
}
|
||||
), host, { host = it })
|
||||
}
|
||||
item {
|
||||
FormTextField(
|
||||
stringResource(
|
||||
when (network) {
|
||||
NetworkType.KCP.type -> R.string.server_lab_path_kcp
|
||||
NetworkType.WS.type -> R.string.server_lab_path_ws
|
||||
NetworkType.HTTP_UPGRADE.type -> R.string.server_lab_path_httpupgrade
|
||||
NetworkType.XHTTP.type -> R.string.server_lab_path_xhttp
|
||||
NetworkType.H2.type -> R.string.server_lab_path_h2
|
||||
NetworkType.GRPC.type -> R.string.server_lab_path_grpc
|
||||
else -> R.string.server_lab_path
|
||||
}
|
||||
), path, { path = it })
|
||||
}
|
||||
if (network == NetworkType.XHTTP.type) {
|
||||
item { FormTextField(stringResource(R.string.server_lab_xhttp_extra), xhttpExtra, { xhttpExtra = it }) }
|
||||
}
|
||||
@@ -459,8 +481,12 @@ fun ServerScreen(
|
||||
item {
|
||||
Button(
|
||||
onClick = {
|
||||
if (address.isBlank()) { context.toast(R.string.server_lab_address); return@Button }
|
||||
if (configType != EConfigType.HYSTERIA2 && (port.toIntOrNull() ?: 0) <= 0) { context.toast(R.string.server_lab_port); return@Button }
|
||||
if (address.isBlank()) {
|
||||
context.toast(R.string.server_lab_address); return@Button
|
||||
}
|
||||
if (configType != EConfigType.HYSTERIA2 && (port.toIntOrNull() ?: 0) <= 0) {
|
||||
context.toast(R.string.server_lab_port); return@Button
|
||||
}
|
||||
val temp = buildProfileItem()
|
||||
scope.launch {
|
||||
isFetchingCert = true
|
||||
@@ -470,7 +496,9 @@ fun ServerScreen(
|
||||
pinnedCA256 = sha256
|
||||
context.toastSuccess(R.string.toast_fetch_cert_sha256_success)
|
||||
}
|
||||
} finally { isFetchingCert = false }
|
||||
} finally {
|
||||
isFetchingCert = false
|
||||
}
|
||||
}
|
||||
},
|
||||
enabled = !isFetchingCert,
|
||||
|
||||
@@ -268,8 +268,10 @@ fun ServerCustomConfigScreen(
|
||||
val targetY = when {
|
||||
lineBottom > scrollY + vh - pad ->
|
||||
(lineBottom - vh + pad).toInt()
|
||||
|
||||
lineTop < scrollY + pad ->
|
||||
(lineTop - pad).toInt()
|
||||
|
||||
else -> null
|
||||
}
|
||||
targetY?.let {
|
||||
@@ -288,9 +290,11 @@ fun ServerCustomConfigScreen(
|
||||
val targetX = when {
|
||||
cursorX < scrollX + pad ->
|
||||
(cursorX - pad).toInt().coerceAtLeast(0)
|
||||
|
||||
cursorX > scrollX + vw - pad ->
|
||||
(cursorX - vw + pad).toInt()
|
||||
.coerceAtMost(horizontalScroll.maxValue)
|
||||
|
||||
else -> null
|
||||
}
|
||||
targetX?.let {
|
||||
|
||||
@@ -14,8 +14,8 @@ 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.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringArrayResource
|
||||
|
||||
@@ -27,8 +27,8 @@ 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.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
|
||||
@@ -141,7 +141,11 @@ fun TaskerScreen(
|
||||
)
|
||||
}
|
||||
) { innerPadding ->
|
||||
Column(modifier = Modifier.fillMaxSize().padding(innerPadding)) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(innerPadding)
|
||||
) {
|
||||
SettingsSwitchItem(
|
||||
title = stringResource(R.string.tasker_start_service),
|
||||
checked = switchState.value,
|
||||
|
||||
@@ -16,8 +16,8 @@ import androidx.compose.material3.ScaffoldDefaults
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
@@ -145,7 +145,7 @@ fun SubEditScreen(
|
||||
val confirmRemove = MmkvManager.decodeSettingsBool(AppConfig.PREF_CONFIRM_REMOVE, false)
|
||||
val scrollState = rememberScrollState()
|
||||
|
||||
fun buildSubItem(): SubscriptionItem? {
|
||||
fun buildSubItem(): SubscriptionItem {
|
||||
val subItem = MmkvManager.decodeSubscription(editSubId) ?: SubscriptionItem()
|
||||
subItem.remarks = remarks
|
||||
subItem.url = url
|
||||
|
||||
@@ -43,9 +43,9 @@ import com.v2ray.ang.R
|
||||
import com.v2ray.ang.compose.AppDivider
|
||||
import com.v2ray.ang.compose.AppTopBar
|
||||
import com.v2ray.ang.compose.ConfirmDialog
|
||||
import com.v2ray.ang.compose.SelectListDialog
|
||||
import com.v2ray.ang.compose.QRCodeDialog
|
||||
import com.v2ray.ang.compose.ReorderableListItem
|
||||
import com.v2ray.ang.compose.SelectListDialog
|
||||
import com.v2ray.ang.compose.SettingsSwitchItem
|
||||
import com.v2ray.ang.compose.colorFabActive
|
||||
import com.v2ray.ang.compose.verticalScrollbar
|
||||
@@ -254,6 +254,7 @@ fun SubSettingScreen(
|
||||
// QRCode
|
||||
showQRCodeBitmap = onShareQRCode(url)
|
||||
}
|
||||
|
||||
1 -> {
|
||||
// Export to clipboard
|
||||
onShareClipboard(url)
|
||||
|
||||
@@ -52,10 +52,10 @@ import com.v2ray.ang.compose.SettingsListItem
|
||||
import com.v2ray.ang.compose.verticalScrollbar
|
||||
import com.v2ray.ang.dto.entities.AssetUrlCache
|
||||
import com.v2ray.ang.dto.entities.AssetUrlItem
|
||||
import com.v2ray.ang.extension.toTrafficString
|
||||
import com.v2ray.ang.extension.toast
|
||||
import com.v2ray.ang.extension.toastError
|
||||
import com.v2ray.ang.extension.toastSuccess
|
||||
import com.v2ray.ang.extension.toTrafficString
|
||||
import com.v2ray.ang.handler.MmkvManager
|
||||
import com.v2ray.ang.handler.SettingsManager
|
||||
import com.v2ray.ang.ui.base.HelperBaseComponentActivity
|
||||
@@ -373,10 +373,16 @@ private fun UserAssetItem(
|
||||
val showEditButton = item.assetUrl.locked != true && item.assetUrl.url != "file"
|
||||
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth().padding(8.dp),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(8.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Column(modifier = Modifier.weight(1f).padding(8.dp)) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(8.dp)
|
||||
) {
|
||||
Text(
|
||||
text = item.assetUrl.remarks,
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
|
||||
@@ -54,10 +54,12 @@ class UserAssetUrlActivity : BaseComponentActivity() {
|
||||
initialRemarks = assetItem.remarks
|
||||
initialUrl = assetItem.url
|
||||
}
|
||||
|
||||
assetUrlQrcode != null -> {
|
||||
initialRemarks = assetNameQrcode
|
||||
initialUrl = assetUrlQrcode
|
||||
}
|
||||
|
||||
else -> {
|
||||
initialRemarks = ""
|
||||
initialUrl = ""
|
||||
|
||||
Reference in new issue
Block a user