Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 397989769c | |||
| 796676abdc | |||
| 3c93ccb86c | |||
| fc8c74184a | |||
| 1939e6b5cf | |||
| 1c2ac9385d | |||
| 7513f1fe07 | |||
| 63e2c02daa | |||
| fec76385e1 | |||
| bf21428746 | |||
| 01ab8dad17 | |||
| 8974f73841 | |||
| d3a2a2413c | |||
| 9b52863270 | |||
| 733914a7a7 |
@@ -12,8 +12,8 @@ android {
|
||||
applicationId = "com.v2ray.ang"
|
||||
minSdk = 21
|
||||
targetSdk = 35
|
||||
versionCode = 640
|
||||
versionName = "1.9.40"
|
||||
versionCode = 642
|
||||
versionName = "1.9.42"
|
||||
multiDexEnabled = true
|
||||
|
||||
val abiFilterList = (properties["ABI_FILTERS"] as? String)?.split(';')
|
||||
|
||||
@@ -42,6 +42,7 @@ object AppConfig {
|
||||
const val PREF_SPEED_ENABLED = "pref_speed_enabled"
|
||||
const val PREF_CONFIRM_REMOVE = "pref_confirm_remove"
|
||||
const val PREF_START_SCAN_IMMEDIATE = "pref_start_scan_immediate"
|
||||
const val PREF_DOUBLE_COLUMN_DISPLAY = "pref_double_column_display"
|
||||
const val PREF_LANGUAGE = "pref_language"
|
||||
const val PREF_UI_MODE_NIGHT = "pref_ui_mode_night"
|
||||
const val PREF_PREFER_IPV6 = "pref_prefer_ipv6"
|
||||
|
||||
@@ -94,7 +94,7 @@ val URI.idnHost: String
|
||||
*
|
||||
* @return The string without whitespace.
|
||||
*/
|
||||
fun String.removeWhiteSpace(): String = replace("\\s+".toRegex(), "")
|
||||
fun String?.removeWhiteSpace(): String? = this?.replace(" ", "")
|
||||
|
||||
/**
|
||||
* Converts the string to a Long value, or returns 0 if the conversion fails.
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.v2ray.ang.dto.EConfigType
|
||||
import com.v2ray.ang.dto.ProfileItem
|
||||
import com.v2ray.ang.dto.V2rayConfig.OutboundBean
|
||||
import com.v2ray.ang.extension.idnHost
|
||||
import com.v2ray.ang.extension.removeWhiteSpace
|
||||
import com.v2ray.ang.util.Utils
|
||||
import java.net.URI
|
||||
|
||||
@@ -132,14 +133,14 @@ object WireguardFmt : FmtBase() {
|
||||
|
||||
dicQuery["publickey"] = config.publicKey.orEmpty()
|
||||
if (config.reserved != null) {
|
||||
dicQuery["reserved"] = Utils.removeWhiteSpace(config.reserved).orEmpty()
|
||||
dicQuery["reserved"] = config.reserved.removeWhiteSpace().orEmpty()
|
||||
}
|
||||
dicQuery["address"] = Utils.removeWhiteSpace(config.localAddress).orEmpty()
|
||||
dicQuery["address"] = config.localAddress.removeWhiteSpace().orEmpty()
|
||||
if (config.mtu != null) {
|
||||
dicQuery["mtu"] = config.mtu.toString()
|
||||
}
|
||||
if (config.preSharedKey != null) {
|
||||
dicQuery["presharedkey"] = Utils.removeWhiteSpace(config.preSharedKey).orEmpty()
|
||||
dicQuery["presharedkey"] = config.preSharedKey.removeWhiteSpace().orEmpty()
|
||||
}
|
||||
|
||||
return toUri(config, config.secretKey, dicQuery)
|
||||
|
||||
@@ -8,9 +8,9 @@ import com.v2ray.ang.dto.EConfigType
|
||||
import com.v2ray.ang.dto.NetworkType
|
||||
import com.v2ray.ang.dto.ProfileItem
|
||||
import com.v2ray.ang.dto.ServerConfig
|
||||
import com.v2ray.ang.extension.removeWhiteSpace
|
||||
import com.v2ray.ang.handler.MmkvManager.decodeServerConfig
|
||||
import com.v2ray.ang.util.JsonUtil
|
||||
import com.v2ray.ang.util.Utils
|
||||
|
||||
object MigrateManager {
|
||||
private const val ID_SERVER_CONFIG = "SERVER_CONFIG"
|
||||
@@ -109,7 +109,7 @@ object MigrateManager {
|
||||
config.insecure = tlsSettings?.allowInsecure
|
||||
config.sni = tlsSettings?.serverName
|
||||
config.fingerPrint = tlsSettings?.fingerprint
|
||||
config.alpn = Utils.removeWhiteSpace(tlsSettings?.alpn?.joinToString(",")).toString()
|
||||
config.alpn = tlsSettings?.alpn?.joinToString(",").removeWhiteSpace().toString()
|
||||
|
||||
config.publicKey = tlsSettings?.publicKey
|
||||
config.shortId = tlsSettings?.shortId
|
||||
@@ -172,10 +172,10 @@ object MigrateManager {
|
||||
|
||||
outbound.settings?.let { wireguard ->
|
||||
config.secretKey = wireguard.secretKey
|
||||
config.localAddress = Utils.removeWhiteSpace((wireguard.address as List<*>).joinToString(",")).toString()
|
||||
config.localAddress = (wireguard.address as List<*>).joinToString(",").removeWhiteSpace().toString()
|
||||
config.publicKey = wireguard.peers?.getOrNull(0)?.publicKey
|
||||
config.mtu = wireguard.mtu
|
||||
config.reserved = Utils.removeWhiteSpace(wireguard.reserved?.joinToString(",")).toString()
|
||||
config.reserved = wireguard.reserved?.joinToString(",").removeWhiteSpace().toString()
|
||||
}
|
||||
return config
|
||||
}
|
||||
@@ -199,7 +199,7 @@ object MigrateManager {
|
||||
outbound.streamSettings?.tlsSettings?.let { tlsSetting ->
|
||||
config.insecure = tlsSetting.allowInsecure
|
||||
config.sni = tlsSetting.serverName
|
||||
config.alpn = Utils.removeWhiteSpace(tlsSetting.alpn?.joinToString(",")).orEmpty()
|
||||
config.alpn = tlsSetting.alpn?.joinToString(",").removeWhiteSpace().orEmpty()
|
||||
|
||||
}
|
||||
config.obfsPassword = outbound.settings?.obfsPassword
|
||||
|
||||
@@ -32,10 +32,10 @@ import android.database.Cursor
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.system.Os
|
||||
import android.widget.Toast
|
||||
import androidx.core.os.bundleOf
|
||||
import com.v2ray.ang.AngApplication
|
||||
import com.v2ray.ang.extension.listenForPackageChanges
|
||||
import com.v2ray.ang.extension.toast
|
||||
import com.v2ray.ang.plugin.PluginContract.METADATA_KEY_ID
|
||||
import java.io.File
|
||||
import java.io.FileNotFoundException
|
||||
@@ -126,7 +126,7 @@ object PluginManager {
|
||||
if (providers.size > 1) {
|
||||
val message =
|
||||
"Conflicting plugins found from: ${providers.joinToString { it.providerInfo.packageName }}"
|
||||
Toast.makeText(AngApplication.application, message, Toast.LENGTH_LONG).show()
|
||||
AngApplication.application.toast(message)
|
||||
throw IllegalStateException(message)
|
||||
}
|
||||
val provider = providers.single().providerInfo
|
||||
@@ -224,8 +224,8 @@ object PluginManager {
|
||||
|
||||
fun ComponentInfo.loadString(key: String) = when (val value = metaData.getString(key)) {
|
||||
is String -> value
|
||||
is Int -> AngApplication.application.packageManager.getResourcesForApplication(applicationInfo)
|
||||
.getString(value)
|
||||
// is Int -> AngApplication.application.packageManager.getResourcesForApplication(applicationInfo)
|
||||
// .getString(value)
|
||||
|
||||
null -> null
|
||||
else -> error("meta-data $key has invalid type ${value.javaClass}")
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.v2ray.ang.service
|
||||
|
||||
import android.annotation.TargetApi
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
@@ -9,6 +8,7 @@ import android.graphics.drawable.Icon
|
||||
import android.os.Build
|
||||
import android.service.quicksettings.Tile
|
||||
import android.service.quicksettings.TileService
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.v2ray.ang.AppConfig
|
||||
import com.v2ray.ang.R
|
||||
@@ -16,7 +16,7 @@ import com.v2ray.ang.util.MessageUtil
|
||||
import com.v2ray.ang.util.Utils
|
||||
import java.lang.ref.SoftReference
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.N)
|
||||
@RequiresApi(Build.VERSION_CODES.N)
|
||||
class QSTileService : TileService() {
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,7 +5,6 @@ import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.FileProvider
|
||||
@@ -14,6 +13,7 @@ import com.v2ray.ang.AppConfig
|
||||
import com.v2ray.ang.BuildConfig
|
||||
import com.v2ray.ang.R
|
||||
import com.v2ray.ang.databinding.ActivityAboutBinding
|
||||
import com.v2ray.ang.extension.toast
|
||||
import com.v2ray.ang.handler.SpeedtestManager
|
||||
import com.v2ray.ang.util.Utils
|
||||
import com.v2ray.ang.util.ZipUtil
|
||||
@@ -195,8 +195,4 @@ class AboutActivity : BaseActivity() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun toast(messageResId: Int) {
|
||||
Toast.makeText(this, getString(messageResId), Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
@@ -21,8 +21,8 @@ import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.GravityCompat
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.google.android.material.navigation.NavigationView
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import com.v2ray.ang.AppConfig
|
||||
@@ -162,7 +162,11 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
|
||||
}
|
||||
|
||||
binding.recyclerView.setHasFixedSize(true)
|
||||
binding.recyclerView.layoutManager = LinearLayoutManager(this)
|
||||
if (MmkvManager.decodeSettingsBool(AppConfig.PREF_DOUBLE_COLUMN_DISPLAY, false)) {
|
||||
binding.recyclerView.layoutManager = GridLayoutManager(this, 2)
|
||||
} else {
|
||||
binding.recyclerView.layoutManager = GridLayoutManager(this, 1)
|
||||
}
|
||||
addCustomDividerToRecyclerView(binding.recyclerView, this, R.drawable.custom_divider)
|
||||
binding.recyclerView.adapter = adapter
|
||||
|
||||
|
||||
@@ -17,13 +17,13 @@ import com.v2ray.ang.databinding.ItemQrcodeBinding
|
||||
import com.v2ray.ang.databinding.ItemRecyclerFooterBinding
|
||||
import com.v2ray.ang.databinding.ItemRecyclerMainBinding
|
||||
import com.v2ray.ang.dto.EConfigType
|
||||
import com.v2ray.ang.dto.ProfileItem
|
||||
import com.v2ray.ang.extension.toast
|
||||
import com.v2ray.ang.handler.AngConfigManager
|
||||
import com.v2ray.ang.handler.MmkvManager
|
||||
import com.v2ray.ang.helper.ItemTouchHelperAdapter
|
||||
import com.v2ray.ang.helper.ItemTouchHelperViewHolder
|
||||
import com.v2ray.ang.service.V2RayServiceManager
|
||||
import com.v2ray.ang.util.Utils
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@@ -37,7 +37,11 @@ class MainRecyclerAdapter(val activity: MainActivity) : RecyclerView.Adapter<Mai
|
||||
private val share_method: Array<out String> by lazy {
|
||||
mActivity.resources.getStringArray(R.array.share_method)
|
||||
}
|
||||
private val share_method_more: Array<out String> by lazy {
|
||||
mActivity.resources.getStringArray(R.array.share_method_more)
|
||||
}
|
||||
var isRunning = false
|
||||
private val doubleColumnDisplay = MmkvManager.decodeSettingsBool(AppConfig.PREF_DOUBLE_COLUMN_DISPLAY, false)
|
||||
|
||||
override fun getItemCount() = mActivity.mainViewModel.serversCache.size + 1
|
||||
|
||||
@@ -45,150 +49,134 @@ class MainRecyclerAdapter(val activity: MainActivity) : RecyclerView.Adapter<Mai
|
||||
if (holder is MainViewHolder) {
|
||||
val guid = mActivity.mainViewModel.serversCache[position].guid
|
||||
val profile = mActivity.mainViewModel.serversCache[position].profile
|
||||
// //filter
|
||||
// if (mActivity.mainViewModel.subscriptionId.isNotEmpty()
|
||||
// && mActivity.mainViewModel.subscriptionId != config.subscriptionId
|
||||
// ) {
|
||||
// holder.itemMainBinding.cardView.visibility = View.GONE
|
||||
// } else {
|
||||
// holder.itemMainBinding.cardView.visibility = View.VISIBLE
|
||||
// }
|
||||
val isCustom = profile.configType == EConfigType.CUSTOM
|
||||
|
||||
val aff = MmkvManager.decodeServerAffiliationInfo(guid)
|
||||
|
||||
holder.itemMainBinding.tvName.text = profile.remarks
|
||||
holder.itemView.setBackgroundColor(Color.TRANSPARENT)
|
||||
|
||||
//Name address
|
||||
holder.itemMainBinding.tvName.text = profile.remarks
|
||||
holder.itemMainBinding.tvStatistics.text = getAddress(profile)
|
||||
holder.itemMainBinding.tvType.text = profile.configType.name
|
||||
|
||||
//TestResult
|
||||
val aff = MmkvManager.decodeServerAffiliationInfo(guid)
|
||||
holder.itemMainBinding.tvTestResult.text = aff?.getTestDelayString().orEmpty()
|
||||
if ((aff?.testDelayMillis ?: 0L) < 0L) {
|
||||
holder.itemMainBinding.tvTestResult.setTextColor(ContextCompat.getColor(mActivity, R.color.colorPingRed))
|
||||
} else {
|
||||
holder.itemMainBinding.tvTestResult.setTextColor(ContextCompat.getColor(mActivity, R.color.colorPing))
|
||||
}
|
||||
|
||||
//layoutIndicator
|
||||
if (guid == MmkvManager.getSelectServer()) {
|
||||
holder.itemMainBinding.layoutIndicator.setBackgroundResource(R.color.colorAccent)
|
||||
} else {
|
||||
holder.itemMainBinding.layoutIndicator.setBackgroundResource(0)
|
||||
}
|
||||
holder.itemMainBinding.tvSubscription.text =
|
||||
if (mActivity.mainViewModel.subscriptionId.isEmpty())
|
||||
MmkvManager.decodeSubscription(profile.subscriptionId)?.remarks.orEmpty()
|
||||
else
|
||||
""
|
||||
|
||||
var shareOptions = share_method.asList()
|
||||
when (profile.configType) {
|
||||
EConfigType.CUSTOM -> {
|
||||
holder.itemMainBinding.tvType.text = mActivity.getString(R.string.server_customize_config)
|
||||
shareOptions = shareOptions.takeLast(1)
|
||||
//subscription remarks
|
||||
val subRemarks = getSubscriptionRemarks(profile)
|
||||
holder.itemMainBinding.tvSubscription.text = subRemarks
|
||||
holder.itemMainBinding.layoutSubscription.visibility = if (subRemarks.isEmpty()) View.GONE else View.VISIBLE
|
||||
|
||||
//layout
|
||||
if (doubleColumnDisplay) {
|
||||
holder.itemMainBinding.layoutShare.visibility = View.GONE
|
||||
holder.itemMainBinding.layoutEdit.visibility = View.GONE
|
||||
holder.itemMainBinding.layoutRemove.visibility = View.GONE
|
||||
holder.itemMainBinding.layoutMore.visibility = View.VISIBLE
|
||||
|
||||
//share method
|
||||
val shareOptions = if (isCustom) share_method_more.asList().takeLast(3) else share_method_more.asList()
|
||||
|
||||
holder.itemMainBinding.layoutMore.setOnClickListener {
|
||||
shareServer(guid, profile, position, shareOptions, if (isCustom) 2 else 0)
|
||||
}
|
||||
} else {
|
||||
holder.itemMainBinding.layoutShare.visibility = View.VISIBLE
|
||||
holder.itemMainBinding.layoutEdit.visibility = View.VISIBLE
|
||||
holder.itemMainBinding.layoutRemove.visibility = View.VISIBLE
|
||||
holder.itemMainBinding.layoutMore.visibility = View.GONE
|
||||
|
||||
//share method
|
||||
val shareOptions = if (isCustom) share_method.asList().takeLast(1) else share_method.asList()
|
||||
|
||||
holder.itemMainBinding.layoutShare.setOnClickListener {
|
||||
shareServer(guid, profile, position, shareOptions, if (isCustom) 2 else 0)
|
||||
}
|
||||
|
||||
else -> {
|
||||
holder.itemMainBinding.tvType.text = profile.configType.name
|
||||
holder.itemMainBinding.layoutEdit.setOnClickListener {
|
||||
editServer(guid, profile)
|
||||
}
|
||||
}
|
||||
|
||||
// Hide xxx:xxx:***/xxx.xxx.xxx.***
|
||||
val strState = "${
|
||||
profile.server?.let {
|
||||
if (it.contains(":"))
|
||||
it.split(":").take(2).joinToString(":", postfix = ":***")
|
||||
else
|
||||
it.split('.').dropLast(1).joinToString(".", postfix = ".***")
|
||||
}
|
||||
} : ${profile.serverPort}"
|
||||
|
||||
holder.itemMainBinding.tvStatistics.text = strState
|
||||
|
||||
holder.itemMainBinding.layoutShare.setOnClickListener {
|
||||
AlertDialog.Builder(mActivity).setItems(shareOptions.toTypedArray()) { _, i ->
|
||||
try {
|
||||
when (i) {
|
||||
0 -> {
|
||||
if (profile.configType == EConfigType.CUSTOM) {
|
||||
shareFullContent(guid)
|
||||
} else {
|
||||
val ivBinding = ItemQrcodeBinding.inflate(LayoutInflater.from(mActivity))
|
||||
ivBinding.ivQcode.setImageBitmap(AngConfigManager.share2QRCode(guid))
|
||||
AlertDialog.Builder(mActivity).setView(ivBinding.root).show()
|
||||
}
|
||||
}
|
||||
|
||||
1 -> {
|
||||
if (AngConfigManager.share2Clipboard(mActivity, guid) == 0) {
|
||||
mActivity.toast(R.string.toast_success)
|
||||
} else {
|
||||
mActivity.toast(R.string.toast_failure)
|
||||
}
|
||||
}
|
||||
|
||||
2 -> shareFullContent(guid)
|
||||
else -> mActivity.toast("else")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}.show()
|
||||
}
|
||||
|
||||
holder.itemMainBinding.layoutEdit.setOnClickListener {
|
||||
val intent = Intent().putExtra("guid", guid)
|
||||
.putExtra("isRunning", isRunning)
|
||||
.putExtra("createConfigType", profile.configType.value)
|
||||
if (profile.configType == EConfigType.CUSTOM) {
|
||||
mActivity.startActivity(intent.setClass(mActivity, ServerCustomConfigActivity::class.java))
|
||||
} else {
|
||||
mActivity.startActivity(intent.setClass(mActivity, ServerActivity::class.java))
|
||||
}
|
||||
}
|
||||
holder.itemMainBinding.layoutRemove.setOnClickListener {
|
||||
if (guid != MmkvManager.getSelectServer()) {
|
||||
if (MmkvManager.decodeSettingsBool(AppConfig.PREF_CONFIRM_REMOVE) == true) {
|
||||
AlertDialog.Builder(mActivity).setMessage(R.string.del_config_comfirm)
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
removeServer(guid, position)
|
||||
}
|
||||
.setNegativeButton(android.R.string.cancel) { _, _ ->
|
||||
//do noting
|
||||
}
|
||||
.show()
|
||||
} else {
|
||||
removeServer(guid, position)
|
||||
}
|
||||
} else {
|
||||
application.toast(R.string.toast_action_not_allowed)
|
||||
holder.itemMainBinding.layoutRemove.setOnClickListener {
|
||||
removeServer(guid, position)
|
||||
}
|
||||
}
|
||||
|
||||
holder.itemMainBinding.infoContainer.setOnClickListener {
|
||||
val selected = MmkvManager.getSelectServer()
|
||||
if (guid != selected) {
|
||||
MmkvManager.setSelectServer(guid)
|
||||
if (!TextUtils.isEmpty(selected)) {
|
||||
notifyItemChanged(mActivity.mainViewModel.getPosition(selected.orEmpty()))
|
||||
}
|
||||
notifyItemChanged(mActivity.mainViewModel.getPosition(guid))
|
||||
if (isRunning) {
|
||||
V2RayServiceManager.stopVService(mActivity)
|
||||
mActivity.lifecycleScope.launch {
|
||||
try {
|
||||
delay(500)
|
||||
V2RayServiceManager.startVService(mActivity)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
setSelectServer(guid)
|
||||
}
|
||||
}
|
||||
if (holder is FooterViewHolder) {
|
||||
if (true) {
|
||||
holder.itemFooterBinding.layoutEdit.visibility = View.INVISIBLE
|
||||
} else {
|
||||
holder.itemFooterBinding.layoutEdit.setOnClickListener {
|
||||
Utils.openUri(mActivity, "${Utils.decode(AppConfig.PromotionUrl)}?t=${System.currentTimeMillis()}")
|
||||
}
|
||||
// if (holder is FooterViewHolder) {
|
||||
// if (true) {
|
||||
// holder.itemFooterBinding.layoutEdit.visibility = View.INVISIBLE
|
||||
// } else {
|
||||
// holder.itemFooterBinding.layoutEdit.setOnClickListener {
|
||||
// Utils.openUri(mActivity, "${Utils.decode(AppConfig.PromotionUrl)}?t=${System.currentTimeMillis()}")
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
private fun getAddress(profile: ProfileItem): String {
|
||||
// Hide xxx:xxx:***/xxx.xxx.xxx.***
|
||||
return "${
|
||||
profile.server?.let {
|
||||
if (it.contains(":"))
|
||||
it.split(":").take(2).joinToString(":", postfix = ":***")
|
||||
else
|
||||
it.split('.').dropLast(1).joinToString(".", postfix = ".***")
|
||||
}
|
||||
} : ${profile.serverPort}"
|
||||
}
|
||||
|
||||
private fun getSubscriptionRemarks(profile: ProfileItem): String {
|
||||
val subRemarks =
|
||||
if (mActivity.mainViewModel.subscriptionId.isEmpty())
|
||||
MmkvManager.decodeSubscription(profile.subscriptionId)?.remarks?.firstOrNull()
|
||||
else
|
||||
null
|
||||
return subRemarks?.toString() ?: ""
|
||||
}
|
||||
|
||||
private fun shareServer(guid: String, profile: ProfileItem, position: Int, shareOptions: List<String>, skip: Int) {
|
||||
AlertDialog.Builder(mActivity).setItems(shareOptions.toTypedArray()) { _, i ->
|
||||
try {
|
||||
when (i + skip) {
|
||||
0 -> showQRCode(guid)
|
||||
1 -> share2Clipboard(guid)
|
||||
2 -> shareFullContent(guid)
|
||||
3 -> editServer(guid, profile)
|
||||
4 -> removeServer(guid, position)
|
||||
else -> mActivity.toast("else")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}.show()
|
||||
}
|
||||
|
||||
private fun showQRCode(guid: String) {
|
||||
val ivBinding = ItemQrcodeBinding.inflate(LayoutInflater.from(mActivity))
|
||||
ivBinding.ivQcode.setImageBitmap(AngConfigManager.share2QRCode(guid))
|
||||
AlertDialog.Builder(mActivity).setView(ivBinding.root).show()
|
||||
}
|
||||
|
||||
private fun share2Clipboard(guid: String) {
|
||||
if (AngConfigManager.share2Clipboard(mActivity, guid) == 0) {
|
||||
mActivity.toast(R.string.toast_success)
|
||||
} else {
|
||||
mActivity.toast(R.string.toast_failure)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,12 +188,64 @@ class MainRecyclerAdapter(val activity: MainActivity) : RecyclerView.Adapter<Mai
|
||||
}
|
||||
}
|
||||
|
||||
private fun editServer(guid: String, profile: ProfileItem) {
|
||||
val intent = Intent().putExtra("guid", guid)
|
||||
.putExtra("isRunning", isRunning)
|
||||
.putExtra("createConfigType", profile.configType.value)
|
||||
if (profile.configType == EConfigType.CUSTOM) {
|
||||
mActivity.startActivity(intent.setClass(mActivity, ServerCustomConfigActivity::class.java))
|
||||
} else {
|
||||
mActivity.startActivity(intent.setClass(mActivity, ServerActivity::class.java))
|
||||
}
|
||||
}
|
||||
|
||||
private fun removeServer(guid: String, position: Int) {
|
||||
if (guid != MmkvManager.getSelectServer()) {
|
||||
if (MmkvManager.decodeSettingsBool(AppConfig.PREF_CONFIRM_REMOVE) == true) {
|
||||
AlertDialog.Builder(mActivity).setMessage(R.string.del_config_comfirm)
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
removeServerSub(guid, position)
|
||||
}
|
||||
.setNegativeButton(android.R.string.cancel) { _, _ ->
|
||||
//do noting
|
||||
}
|
||||
.show()
|
||||
} else {
|
||||
removeServerSub(guid, position)
|
||||
}
|
||||
} else {
|
||||
application.toast(R.string.toast_action_not_allowed)
|
||||
}
|
||||
}
|
||||
|
||||
private fun removeServerSub(guid: String, position: Int) {
|
||||
mActivity.mainViewModel.removeServer(guid)
|
||||
notifyItemRemoved(position)
|
||||
notifyItemRangeChanged(position, mActivity.mainViewModel.serversCache.size)
|
||||
}
|
||||
|
||||
private fun setSelectServer(guid: String) {
|
||||
val selected = MmkvManager.getSelectServer()
|
||||
if (guid != selected) {
|
||||
MmkvManager.setSelectServer(guid)
|
||||
if (!TextUtils.isEmpty(selected)) {
|
||||
notifyItemChanged(mActivity.mainViewModel.getPosition(selected.orEmpty()))
|
||||
}
|
||||
notifyItemChanged(mActivity.mainViewModel.getPosition(guid))
|
||||
if (isRunning) {
|
||||
V2RayServiceManager.stopVService(mActivity)
|
||||
mActivity.lifecycleScope.launch {
|
||||
try {
|
||||
delay(500)
|
||||
V2RayServiceManager.startVService(mActivity)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
|
||||
return when (viewType) {
|
||||
VIEW_TYPE_ITEM ->
|
||||
|
||||
@@ -4,7 +4,6 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.v2ray.ang.R
|
||||
import com.v2ray.ang.databinding.ItemRecyclerBypassListBinding
|
||||
import com.v2ray.ang.dto.AppInfo
|
||||
|
||||
@@ -35,7 +34,7 @@ class PerAppProxyAdapter(val activity: BaseActivity, val apps: List<AppInfo>, bl
|
||||
val view = View(ctx)
|
||||
view.layoutParams = ViewGroup.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ctx.resources.getDimensionPixelSize(R.dimen.view_height_dp64) * 0
|
||||
0
|
||||
)
|
||||
BaseViewHolder(view)
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ class ServerCustomConfigActivity : BaseActivity() {
|
||||
CustomFmt.parse(binding.editor.text.toString())
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
ToastCompat.makeText(this, "${getString(R.string.toast_malformed_josn)} ${e.cause?.message}", Toast.LENGTH_LONG).show()
|
||||
toast("${getString(R.string.toast_malformed_josn)} ${e.cause?.message}")
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
@@ -238,6 +238,7 @@ class SettingsActivity : BaseActivity() {
|
||||
AppConfig.PREF_SPEED_ENABLED,
|
||||
AppConfig.PREF_CONFIRM_REMOVE,
|
||||
AppConfig.PREF_START_SCAN_IMMEDIATE,
|
||||
AppConfig.PREF_DOUBLE_COLUMN_DISPLAY,
|
||||
AppConfig.PREF_PREFER_IPV6,
|
||||
AppConfig.PREF_PROXY_SHARING,
|
||||
AppConfig.PREF_ALLOW_INSECURE
|
||||
|
||||
@@ -53,7 +53,10 @@ class SubSettingRecyclerAdapter(val activity: SubSettingActivity) : RecyclerView
|
||||
|
||||
if (TextUtils.isEmpty(subItem.url)) {
|
||||
holder.itemSubSettingBinding.layoutShare.visibility = View.INVISIBLE
|
||||
holder.itemSubSettingBinding.chkEnable.visibility = View.INVISIBLE
|
||||
} else {
|
||||
holder.itemSubSettingBinding.layoutShare.visibility = View.VISIBLE
|
||||
holder.itemSubSettingBinding.chkEnable.visibility = View.VISIBLE
|
||||
holder.itemSubSettingBinding.layoutShare.setOnClickListener {
|
||||
AlertDialog.Builder(mActivity)
|
||||
.setItems(share_method.asList().toTypedArray()) { _, i ->
|
||||
|
||||
@@ -17,8 +17,14 @@ object HttpUtil {
|
||||
* @return The ASCII representation of the URL.
|
||||
*/
|
||||
fun idnToASCII(str: String): String {
|
||||
val url = URL(str)
|
||||
return URL(url.protocol, IDN.toASCII(url.host, IDN.ALLOW_UNASSIGNED), url.port, url.file).toExternalForm()
|
||||
val url = URI(str)
|
||||
val host = url.host
|
||||
val asciiHost = IDN.toASCII(url.host, IDN.ALLOW_UNASSIGNED)
|
||||
if (host != asciiHost) {
|
||||
return str.replace(host, asciiHost)
|
||||
} else {
|
||||
return str
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,7 +4,6 @@ import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.res.Configuration.UI_MODE_NIGHT_MASK
|
||||
import android.content.res.Configuration.UI_MODE_NIGHT_NO
|
||||
import android.os.Build
|
||||
@@ -437,25 +436,6 @@ object Utils {
|
||||
.replace("|", "%7C")
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove white space from a string.
|
||||
*
|
||||
* @param str The string to process.
|
||||
* @return The string without white space.
|
||||
*/
|
||||
fun removeWhiteSpace(str: String?): String? {
|
||||
return str?.replace(" ", "")
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the device is a TV.
|
||||
*
|
||||
* @param context The context to use.
|
||||
* @return True if the device is a TV, false otherwise.
|
||||
*/
|
||||
fun isTv(context: Context): Boolean =
|
||||
context.packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)
|
||||
|
||||
/**
|
||||
* Find a free port from a list of ports.
|
||||
*
|
||||
|
||||
@@ -162,7 +162,7 @@ class MainViewModel(application: Application) : AndroidViewModel(application) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (keywordFilter.isEmpty() || profile.remarks.contains(keywordFilter)) {
|
||||
if (keywordFilter.isEmpty() || profile.remarks.lowercase().contains(keywordFilter.lowercase())) {
|
||||
serversCache.add(ServersCache(guid, profile))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +73,7 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application
|
||||
AppConfig.PREF_BYPASS_APPS,
|
||||
AppConfig.PREF_CONFIRM_REMOVE,
|
||||
AppConfig.PREF_START_SCAN_IMMEDIATE,
|
||||
AppConfig.PREF_DOUBLE_COLUMN_DISPLAY,
|
||||
AppConfig.SUBSCRIPTION_AUTO_UPDATE,
|
||||
AppConfig.PREF_FRAGMENT_ENABLED,
|
||||
AppConfig.PREF_MUX_ENABLED,
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z" />
|
||||
|
||||
</vector>
|
||||
@@ -0,0 +1,7 @@
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
<solid android:color="@color/divider_color_light" />
|
||||
<size
|
||||
android:width="48dp"
|
||||
android:height="48dp"/>
|
||||
</shape>
|
||||
@@ -0,0 +1,11 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z" />
|
||||
|
||||
</vector>
|
||||
@@ -1,7 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true">
|
||||
|
||||
<LinearLayout xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
@@ -57,7 +58,7 @@
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_share"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp72"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
@@ -81,7 +82,7 @@
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_restore"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp72"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
@@ -113,7 +114,7 @@
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_soure_ccode"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp72"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
@@ -137,7 +138,7 @@
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_oss_licenses"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp72"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
@@ -161,7 +162,7 @@
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_feedback"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp72"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
@@ -186,7 +187,7 @@
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_tg_channel"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp72"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
@@ -210,7 +211,7 @@
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_privacy_policy"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp72"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
@@ -233,7 +234,7 @@
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp72"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
android:padding="@dimen/padding_spacing_dp16">
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
@@ -19,8 +20,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="@dimen/padding_spacing_dp16"
|
||||
android:paddingEnd="@dimen/padding_spacing_dp16">
|
||||
android:padding="@dimen/padding_spacing_dp16">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp64"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
@@ -83,7 +83,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scrollbars="vertical"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
|
||||
tools:context=".ui.PerAppProxyActivity" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -4,6 +4,7 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
tools:context=".ui.LogcatActivity">
|
||||
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
|
||||
@@ -47,7 +47,8 @@
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/tab_group"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp64"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="@dimen/padding_spacing_dp8"
|
||||
app:tabIndicatorFullWidth="false"
|
||||
app:tabMode="scrollable"
|
||||
app:tabTextAppearance="@style/TabLayoutTextStyle" />
|
||||
@@ -64,19 +65,24 @@
|
||||
android:id="@+id/layout_test"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp64"
|
||||
android:background="@color/colorPrimary"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:gravity="center|start"
|
||||
android:nextFocusLeft="@+id/recycler_view"
|
||||
android:orientation="vertical"
|
||||
android:nextFocusRight="@+id/fab">
|
||||
|
||||
<View
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="1dp"
|
||||
android:background="@color/divider_color_light" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_test_state"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:maxLines="2"
|
||||
android:minLines="1"
|
||||
android:gravity="start|center"
|
||||
android:paddingStart="@dimen/padding_spacing_dp16"
|
||||
android:text="@string/connection_test_pending"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small" />
|
||||
@@ -85,20 +91,18 @@
|
||||
</LinearLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/fabProgressCircle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp16">
|
||||
android:layout_marginEnd="@dimen/padding_spacing_dp16"
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp8">
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/fab"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_margin="@dimen/padding_spacing_dp16"
|
||||
android:layout_marginBottom="@dimen/view_height_dp64"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:nextFocusLeft="@+id/layout_test"
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:fitsSystemWindows="true"
|
||||
tools:context=".ui.SubSettingActivity">
|
||||
|
||||
<LinearLayout
|
||||
@@ -31,7 +32,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_remarks"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text" />
|
||||
</LinearLayout>
|
||||
|
||||
@@ -117,7 +118,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_port"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text" />
|
||||
</LinearLayout>
|
||||
|
||||
@@ -135,7 +136,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_protocol"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/routing_settings_protocol_tip"
|
||||
android:inputType="text" />
|
||||
</LinearLayout>
|
||||
@@ -154,7 +155,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_network"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/routing_settings_network_tip"
|
||||
android:inputType="text" />
|
||||
</LinearLayout>
|
||||
@@ -171,9 +172,11 @@
|
||||
android:text="@string/routing_settings_outbound_tag" />
|
||||
|
||||
<Spinner
|
||||
android:layout_marginTop="@dimen/padding_spacing_dp8"
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp8"
|
||||
android:id="@+id/sp_outbound_tag"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:entries="@array/outbound_tag" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
tools:context=".ui.RoutingSettingActivity">
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
@@ -28,6 +29,8 @@
|
||||
android:text="@string/routing_settings_domain_strategy" />
|
||||
|
||||
<Spinner
|
||||
android:layout_marginTop="@dimen/padding_spacing_dp8"
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp8"
|
||||
android:id="@+id/sp_domain_strategy"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
tools:context=".ui.ServerCustomConfigActivity">
|
||||
|
||||
<LinearLayout
|
||||
@@ -51,7 +52,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_remarks"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
tools:context=".ui.ServerActivity">
|
||||
|
||||
<LinearLayout
|
||||
@@ -27,7 +28,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_id"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -46,7 +47,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_obfs_password"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -65,7 +66,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_port_hop"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -84,7 +85,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_port_hop_interval"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="number" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -103,7 +104,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_bandwidth_down"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -122,7 +123,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_bandwidth_up"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
tools:context=".ui.ServerActivity">
|
||||
|
||||
<LinearLayout
|
||||
@@ -27,7 +28,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_id"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -45,9 +46,11 @@
|
||||
android:text="@string/server_lab_security3" />
|
||||
|
||||
<Spinner
|
||||
android:layout_marginTop="@dimen/padding_spacing_dp8"
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp8"
|
||||
android:id="@+id/sp_security"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:entries="@array/ss_securitys" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
tools:context=".ui.ServerActivity">
|
||||
|
||||
<LinearLayout
|
||||
@@ -28,7 +29,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_security"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -47,7 +48,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_id"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
tools:context=".ui.ServerActivity">
|
||||
|
||||
<LinearLayout
|
||||
@@ -27,7 +28,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_id"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
tools:context=".ui.ServerActivity">
|
||||
|
||||
<LinearLayout
|
||||
@@ -27,7 +28,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_id"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -44,9 +45,11 @@
|
||||
android:text="@string/server_lab_flow" />
|
||||
|
||||
<Spinner
|
||||
android:layout_marginTop="@dimen/padding_spacing_dp8"
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp8"
|
||||
android:id="@+id/sp_flow"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:entries="@array/flows" />
|
||||
</LinearLayout>
|
||||
|
||||
@@ -64,7 +67,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_security"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text"
|
||||
android:text="none" />
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
tools:context=".ui.ServerActivity">
|
||||
|
||||
<LinearLayout
|
||||
@@ -27,7 +28,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_id"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -44,9 +45,11 @@
|
||||
android:text="@string/server_lab_security" />
|
||||
|
||||
<Spinner
|
||||
android:layout_marginTop="@dimen/padding_spacing_dp8"
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp8"
|
||||
android:id="@+id/sp_security"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:entries="@array/securitys" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
tools:context=".ui.ServerActivity">
|
||||
|
||||
<LinearLayout
|
||||
@@ -27,7 +28,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_id"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -47,7 +48,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_public_key"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -66,7 +67,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_preshared_key"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -90,7 +91,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_reserved1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -110,7 +111,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_local_address"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text" />
|
||||
</LinearLayout>
|
||||
|
||||
@@ -128,7 +129,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_local_mtu"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="number" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
android:orientation="vertical"
|
||||
tools:context=".ui.SettingsActivity">
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:fitsSystemWindows="true"
|
||||
tools:context=".ui.SubSettingActivity">
|
||||
|
||||
<LinearLayout
|
||||
@@ -43,7 +44,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_remarks"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -87,7 +88,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_filter"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -151,7 +152,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_pre_profile"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/sub_setting_pre_profile_tip"
|
||||
android:inputType="text" />
|
||||
|
||||
@@ -171,7 +172,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_next_profile"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/sub_setting_pre_profile_tip"
|
||||
android:inputType="text" />
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
tools:context=".ui.SubSettingActivity">
|
||||
|
||||
<com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
|
||||
@@ -3,13 +3,15 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/padding_spacing_dp16"
|
||||
tools:context=".ui.TaskerActivity">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp64">
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="@dimen/padding_spacing_dp8">
|
||||
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
android:id="@+id/switch_start_service"
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
tools:context=".ui.UserAssetUrlActivity">
|
||||
|
||||
<LinearLayout
|
||||
@@ -42,7 +43,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_remarks"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -16,9 +16,11 @@
|
||||
android:orientation="vertical">
|
||||
|
||||
<Spinner
|
||||
android:layout_marginTop="@dimen/padding_spacing_dp8"
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp8"
|
||||
android:id="@+id/sp_subscriptionId"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48" />
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -36,7 +38,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_keyword"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -5,17 +5,18 @@
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:padding="@dimen/padding_spacing_dp8"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="@dimen/view_height_dp72"
|
||||
android:layout_height="@dimen/view_height_dp72"
|
||||
android:padding="@dimen/padding_spacing_dp16" />
|
||||
android:layout_width="@dimen/view_height_dp48"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:padding="@dimen/padding_spacing_dp8" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/view_height_dp72"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.0"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
@@ -42,6 +43,6 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:clickable="false"
|
||||
android:focusable="false"
|
||||
android:paddingEnd="@dimen/padding_spacing_dp16"/>
|
||||
android:padding="@dimen/padding_spacing_dp8" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -8,9 +8,10 @@
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_edit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:visibility="invisible"
|
||||
android:orientation="horizontal"
|
||||
android:padding="@dimen/padding_spacing_dp16">
|
||||
|
||||
@@ -18,8 +19,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center|left"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="@dimen/padding_spacing_dp16">
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
@@ -10,78 +10,195 @@
|
||||
<LinearLayout
|
||||
android:id="@+id/info_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp72"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:gravity="center"
|
||||
android:nextFocusRight="@+id/layout_share"
|
||||
android:orientation="horizontal">
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="@dimen/padding_spacing_dp8"
|
||||
android:paddingEnd="@dimen/padding_spacing_dp4"
|
||||
android:paddingStart="@dimen/padding_spacing_dp4"
|
||||
android:paddingBottom="@dimen/padding_spacing_dp8">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_indicator"
|
||||
android:layout_width="6dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_width="@dimen/padding_spacing_dp4"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:orientation="vertical" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="@dimen/padding_spacing_dp16">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLines="2"
|
||||
android:minLines="1"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Subhead" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_statistics"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:lines="1"
|
||||
android:paddingTop="@dimen/padding_spacing_dp8"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="@dimen/padding_spacing_dp8">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLines="2"
|
||||
android:minLines="1"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Subhead" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="@dimen/padding_spacing_dp8">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/layout_subscription"
|
||||
android:layout_width="@dimen/image_size_dp24"
|
||||
android:layout_height="@dimen/image_size_dp24"
|
||||
android:layout_gravity="bottom"
|
||||
android:layout_marginEnd="@dimen/padding_spacing_dp4"
|
||||
android:background="@drawable/ic_circle">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_subscription"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
android:textSize="11sp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_statistics"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:lines="1"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_share"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:gravity="center"
|
||||
android:nextFocusLeft="@+id/info_container"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/padding_spacing_dp8">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/image_size_dp24"
|
||||
app:srcCompat="@drawable/ic_share_24dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_edit"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/padding_spacing_dp8">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="@dimen/image_size_dp24"
|
||||
android:layout_height="@dimen/image_size_dp24"
|
||||
app:srcCompat="@drawable/ic_edit_24dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_remove"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/padding_spacing_dp8">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="@dimen/image_size_dp24"
|
||||
android:layout_height="@dimen/image_size_dp24"
|
||||
app:srcCompat="@drawable/ic_delete_24dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_more"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/padding_spacing_dp8">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="@dimen/image_size_dp24"
|
||||
android:layout_height="@dimen/image_size_dp24"
|
||||
app:srcCompat="@drawable/ic_more_vert_24dp" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="4dp"
|
||||
android:paddingEnd="@dimen/padding_spacing_dp16">
|
||||
android:paddingStart="@dimen/padding_spacing_dp8"
|
||||
android:paddingTop="@dimen/padding_spacing_dp8"
|
||||
android:paddingEnd="@dimen/padding_spacing_dp8">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_subscription"
|
||||
android:id="@+id/tv_type"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:lines="1"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
android:textColor="@color/color_secondary"
|
||||
android:textColor="@color/colorConfigType"
|
||||
android:textSize="11sp"
|
||||
tools:text="Sub" />
|
||||
tools:text="VLESS" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_test_result"
|
||||
@@ -92,90 +209,11 @@
|
||||
android:textColor="@color/colorPing"
|
||||
android:textSize="11sp"
|
||||
tools:text="214ms" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_share"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/view_height_dp72"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:gravity="center"
|
||||
android:nextFocusLeft="@+id/info_container"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/padding_spacing_dp8">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/image_size_dp24"
|
||||
app:srcCompat="@drawable/ic_share_24dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_edit"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/view_height_dp72"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/padding_spacing_dp8">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="@dimen/image_size_dp24"
|
||||
android:layout_height="@dimen/image_size_dp24"
|
||||
app:srcCompat="@drawable/ic_edit_24dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_remove"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/view_height_dp72"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/padding_spacing_dp8">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="@dimen/image_size_dp24"
|
||||
android:layout_height="@dimen/image_size_dp24"
|
||||
app:srcCompat="@drawable/ic_delete_24dp" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="right"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="4dp"
|
||||
android:paddingEnd="@dimen/padding_spacing_dp16">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_type"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:lines="1"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
android:textColor="@color/colorConfigType"
|
||||
android:textSize="11sp" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<LinearLayout
|
||||
android:id="@+id/info_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp90"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
@@ -17,15 +17,14 @@
|
||||
android:gravity="center"
|
||||
android:nextFocusRight="@+id/layout_edit"
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="@dimen/padding_spacing_dp8"
|
||||
android:paddingBottom="@dimen/padding_spacing_dp8">
|
||||
android:padding="@dimen/padding_spacing_dp8">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="@dimen/padding_spacing_dp16">
|
||||
android:padding="@dimen/padding_spacing_dp8">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
@@ -68,11 +67,10 @@
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/view_height_dp90"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="@dimen/padding_spacing_dp16"
|
||||
android:paddingEnd="@dimen/padding_spacing_dp16">
|
||||
android:padding="@dimen/padding_spacing_dp8">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_edit"
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<LinearLayout
|
||||
android:id="@+id/info_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp90"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
@@ -17,15 +17,14 @@
|
||||
android:gravity="center"
|
||||
android:nextFocusRight="@+id/layout_edit"
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="@dimen/padding_spacing_dp8"
|
||||
android:paddingBottom="@dimen/padding_spacing_dp8">
|
||||
android:padding="@dimen/padding_spacing_dp8">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="@dimen/padding_spacing_dp16">
|
||||
android:padding="@dimen/padding_spacing_dp8">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_name"
|
||||
@@ -45,11 +44,10 @@
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/view_height_dp90"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="@dimen/padding_spacing_dp16"
|
||||
android:paddingEnd="@dimen/padding_spacing_dp16">
|
||||
android:padding="@dimen/padding_spacing_dp8">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="@dimen/padding_spacing_dp16">
|
||||
android:padding="@dimen/padding_spacing_dp8">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_remarks"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -49,7 +49,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_address"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -68,7 +68,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_port"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="number" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -19,9 +19,11 @@
|
||||
android:text="@string/server_lab_stream_security" />
|
||||
|
||||
<Spinner
|
||||
android:layout_marginTop="@dimen/padding_spacing_dp8"
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp8"
|
||||
android:id="@+id/sp_stream_security"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:entries="@array/streamsecurityxs"
|
||||
android:nextFocusDown="@+id/et_sni" />
|
||||
|
||||
@@ -42,7 +44,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_sni"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text"
|
||||
android:nextFocusDown="@+id/sp_stream_fingerprint" />
|
||||
|
||||
@@ -61,9 +63,11 @@
|
||||
android:text="@string/server_lab_stream_fingerprint" />
|
||||
|
||||
<Spinner
|
||||
android:layout_marginTop="@dimen/padding_spacing_dp8"
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp8"
|
||||
android:id="@+id/sp_stream_fingerprint"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:entries="@array/streamsecurity_utls"
|
||||
android:nextFocusDown="@+id/sp_stream_alpn" />
|
||||
|
||||
@@ -82,9 +86,11 @@
|
||||
android:text="@string/server_lab_stream_alpn" />
|
||||
|
||||
<Spinner
|
||||
android:layout_marginTop="@dimen/padding_spacing_dp8"
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp8"
|
||||
android:id="@+id/sp_stream_alpn"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:entries="@array/streamsecurity_alpn"
|
||||
android:nextFocusDown="@+id/sp_allow_insecure" />
|
||||
|
||||
@@ -102,9 +108,11 @@
|
||||
android:text="@string/server_lab_allow_insecure" />
|
||||
|
||||
<Spinner
|
||||
android:layout_marginTop="@dimen/padding_spacing_dp8"
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp8"
|
||||
android:id="@+id/sp_allow_insecure"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:entries="@array/allowinsecures" />
|
||||
</LinearLayout>
|
||||
|
||||
@@ -123,7 +131,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_public_key"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text"
|
||||
android:nextFocusDown="@+id/sp_stream_fingerprint" />
|
||||
|
||||
@@ -144,7 +152,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_short_id"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text"
|
||||
android:nextFocusDown="@+id/sp_stream_fingerprint" />
|
||||
|
||||
@@ -165,7 +173,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_spider_x"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text"
|
||||
android:nextFocusDown="@+id/sp_stream_fingerprint" />
|
||||
|
||||
|
||||
@@ -19,9 +19,11 @@
|
||||
android:text="@string/server_lab_stream_security" />
|
||||
|
||||
<Spinner
|
||||
android:layout_marginTop="@dimen/padding_spacing_dp8"
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp8"
|
||||
android:id="@+id/sp_stream_security"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:entries="@array/streamsecuritys"
|
||||
android:nextFocusDown="@+id/et_sni" />
|
||||
|
||||
@@ -42,7 +44,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_sni"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text"
|
||||
android:nextFocusDown="@+id/sp_stream_fingerprint" />
|
||||
|
||||
@@ -61,9 +63,11 @@
|
||||
android:text="@string/server_lab_allow_insecure" />
|
||||
|
||||
<Spinner
|
||||
android:layout_marginTop="@dimen/padding_spacing_dp8"
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp8"
|
||||
android:id="@+id/sp_allow_insecure"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:entries="@array/allowinsecures" />
|
||||
|
||||
|
||||
@@ -81,7 +85,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_pinsha256"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -29,9 +29,11 @@
|
||||
android:text="@string/server_lab_network" />
|
||||
|
||||
<Spinner
|
||||
android:layout_marginTop="@dimen/padding_spacing_dp8"
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp8"
|
||||
android:id="@+id/sp_network"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:entries="@array/networks" />
|
||||
</LinearLayout>
|
||||
|
||||
@@ -48,9 +50,11 @@
|
||||
android:text="@string/server_lab_head_type" />
|
||||
|
||||
<Spinner
|
||||
android:layout_marginTop="@dimen/padding_spacing_dp8"
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp8"
|
||||
android:id="@+id/sp_header_type"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48" />
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
@@ -68,7 +72,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_request_host"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text" />
|
||||
</LinearLayout>
|
||||
|
||||
@@ -88,7 +92,7 @@
|
||||
<EditText
|
||||
android:id="@+id/et_path"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_dp48"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -216,6 +216,9 @@
|
||||
<string name="title_pref_append_http_proxy">Append HTTP Proxy to VPN</string>
|
||||
<string name="summary_pref_append_http_proxy">HTTP proxy will be used directly from (browser/ some supported apps), without going through the virtual NIC device (Android 10+)</string>
|
||||
|
||||
<string name="title_pref_double_column_display">Enable double column display</string>
|
||||
<string name="summary_pref_double_column_display">The profile list is displayed in double columns, allowing more content to be displayed on the screen. You need to restart the application to take effect.</string>
|
||||
|
||||
<!-- AboutActivity -->
|
||||
<string name="title_pref_feedback">ملاحظات</string>
|
||||
<string name="summary_pref_feedback">ملاحظات التحسينات أو الأخطاء إلى GitHub</string>
|
||||
@@ -317,6 +320,14 @@
|
||||
<item>تصدير التكوين الكامل إلى الحافظة</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="share_method_more">
|
||||
<item>QRcode</item>
|
||||
<item>Export to clipboard</item>
|
||||
<item>Export full configuration to clipboard</item>
|
||||
<item>Edit</item>
|
||||
<item>Delete</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="share_sub_method">
|
||||
<item>رمز استجابة سريعة (QRcode)</item>
|
||||
<item>تصدير إلى الحافظة</item>
|
||||
|
||||
@@ -216,6 +216,9 @@
|
||||
<string name="title_pref_append_http_proxy">Append HTTP Proxy to VPN</string>
|
||||
<string name="summary_pref_append_http_proxy">HTTP proxy will be used directly from (browser/ some supported apps), without going through the virtual NIC device (Android 10+)</string>
|
||||
|
||||
<string name="title_pref_double_column_display">Enable double column display</string>
|
||||
<string name="summary_pref_double_column_display">The profile list is displayed in double columns, allowing more content to be displayed on the screen. You need to restart the application to take effect.</string>
|
||||
|
||||
<!-- AboutActivity -->
|
||||
<string name="title_pref_feedback">মতামত</string>
|
||||
<string name="summary_pref_feedback">মতামত উন্নয়ন বা বাগগুলি GitHub-এ পাঠান</string>
|
||||
@@ -309,12 +312,21 @@
|
||||
<string name="title_pref_fragment_length">ফ্র্যাগমেন্ট দৈর্ঘ্য (ন্যূনতম-সর্বাধিক)</string>
|
||||
<string name="title_pref_fragment_interval">ফ্র্যাগমেন্ট ইন্টারভ্যাল (ন্যূনতম-সর্বাধিক)</string>
|
||||
<string name="title_pref_fragment_enabled">ফ্র্যাগমেন্ট সক্রিয় করুন</string>
|
||||
|
||||
<string-array name="share_method">
|
||||
<item>QR কোড</item>
|
||||
<item>ক্লিপবোর্ডে রপ্তানি করুন</item>
|
||||
<item>পূর্ণ কনফিগারেশন ক্লিপবোর্ডে রপ্তানি করুন</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="share_method_more">
|
||||
<item>QRcode</item>
|
||||
<item>Export to clipboard</item>
|
||||
<item>Export full configuration to clipboard</item>
|
||||
<item>Edit</item>
|
||||
<item>Delete</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="share_sub_method">
|
||||
<item>QR কোড</item>
|
||||
<item>ক্লিপবোর্ডে রপ্তানি করুন</item>
|
||||
|
||||
@@ -216,6 +216,9 @@
|
||||
<string name="title_pref_append_http_proxy">پروکسی HTTP ن و VPN ازاف کۊنین</string>
|
||||
<string name="summary_pref_append_http_proxy">پروکسی HTTP ن موسقیمن ز (مۊرۊرگر/ی قرد ز برنومیل لادراری بیڌه)، بؽ استفاڌه ز دسگا NIC مجازی (Android 10+) استفاڌه ابۊ.</string>
|
||||
|
||||
<string name="title_pref_double_column_display">Enable double column display</string>
|
||||
<string name="summary_pref_double_column_display">The profile list is displayed in double columns, allowing more content to be displayed on the screen. You need to restart the application to take effect.</string>
|
||||
|
||||
<!-- AboutActivity -->
|
||||
<string name="title_pref_feedback">فشناڌن منشڌ</string>
|
||||
<string name="summary_pref_feedback">فشناڌن منشڌ یا داسوو موشکلا من Github</string>
|
||||
@@ -325,6 +328,14 @@
|
||||
<item>و در کشیڌن پوی کانفیگ من کلیپ بورد</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="share_method_more">
|
||||
<item>QRcode</item>
|
||||
<item>Export to clipboard</item>
|
||||
<item>Export full configuration to clipboard</item>
|
||||
<item>Edit</item>
|
||||
<item>Delete</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="share_sub_method">
|
||||
<item>QRcode</item>
|
||||
<item>و در کشیڌن من کلیپ بورد</item>
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
<string name="server_lab_spider_x">SpiderX</string>
|
||||
<string name="server_lab_secret_key">کلید خصوصی</string>
|
||||
<string name="server_lab_reserved">Reserved (اختیاری، جدا شده با کاما)</string>
|
||||
<string name="server_lab_local_address">آدرس محلی IPV4 (اختیاری)</string>
|
||||
<string name="server_lab_local_address">آدرس محلی (IPv4/IPv6 اختیاری، جدا شده با کاما)</string>
|
||||
<string name="server_lab_local_mtu">MTU (اختیاری، پیشفرض 1420)</string>
|
||||
<string name="toast_success">با موفقیت انجام شد</string>
|
||||
<string name="toast_failure">شکست</string>
|
||||
@@ -101,7 +101,7 @@
|
||||
<string name="server_lab_content">محتوا</string>
|
||||
<string name="toast_none_data_clipboard">هیچ داده ای در کلیپ بورد وجود ندارد</string>
|
||||
<string name="toast_invalid_url">نشانی اینترنتی معتبر نیست</string>
|
||||
<string name="toast_insecure_url_protocol">لطفاً از آدرس اشتراک پروتکل HTTP ناامن استفاده نکنید</string>
|
||||
<string name="toast_insecure_url_protocol">لطفاً از آدرس های اشتراک پروتکل HTTP ناامن استفاده نکنید</string>
|
||||
<string name="server_lab_need_inbound">اطمینان حاصل کنید که پورت ورودی با تنظیمات مطابقت دارد</string>
|
||||
<string name="toast_malformed_josn">کانفیگ درست نیست</string>
|
||||
<string name="server_lab_request_host6">هاست (SNI) (اختیاری)</string>
|
||||
@@ -143,7 +143,7 @@
|
||||
<string name="title_advanced">تنظیمات پیشرفته</string>
|
||||
<string name="title_vpn_settings">تنظیمات VPN</string>
|
||||
<string name="title_pref_per_app_proxy">پروکسی به تفکیک برنامه</string>
|
||||
<string name="summary_pref_per_app_proxy">عمومی: برنامه بررسی شده پروکسی است، اتصال مستقیم بدون بررسی است. \nحالت دور زدن: برنامه بررسی شده مستقیما متصل است، پراکسی بررسی نشده است. \nگزینهای برای انتخاب خودکار پروکسی برنامه در منو است.</string>
|
||||
<string name="summary_pref_per_app_proxy">عمومی: برنامه انتخاب شده از طریق یک پروکسی متصل می شود، برنامه انتخاب نشده مستقیماً متصل می شود. \nحالت دور زدن: برنامه انتخاب شده مستقیماً متصل می شود، برنامه انتخاب نشده از طریق یک پروکسی متصل می شود. \nانتخاب خودکار برنامه های پراکسی در منو امکان پذیر است.</string>
|
||||
<string name="title_pref_is_booted">اتصال خودکار هنگام راه اندازی</string>
|
||||
<string name="summary_pref_is_booted">هنگام راه اندازی به طور خودکار به سرور انتخابی متصل می شود که ممکن است ناموفق باشد.</string>
|
||||
|
||||
@@ -214,6 +214,9 @@
|
||||
<string name="title_pref_append_http_proxy">پروکسی HTTP را به VPN اضافه کنید</string>
|
||||
<string name="summary_pref_append_http_proxy">پروکسی HTTP مستقیماً از (مرورگر/برخی برنامههای پشتیبانیشده)، بدون استفاده از دستگاه NIC مجازی (Android 10+) استفاده میشود.</string>
|
||||
|
||||
<string name="title_pref_double_column_display">Enable double column display</string>
|
||||
<string name="summary_pref_double_column_display">The profile list is displayed in double columns, allowing more content to be displayed on the screen. You need to restart the application to take effect.</string>
|
||||
|
||||
<!-- AboutActivity -->
|
||||
<string name="title_pref_feedback">بازخورد</string>
|
||||
<string name="summary_pref_feedback">بازخورد یا گزارش اشکالات در گیت هاب</string>
|
||||
@@ -315,12 +318,21 @@
|
||||
<string name="title_pref_fragment_length">طول بسته های فرگمنت (حداقل-حداکثر)</string>
|
||||
<string name="title_pref_fragment_interval">فاصله بین بسته های فرگمنت (حداقل-حداکثر)</string>
|
||||
<string name="title_pref_fragment_enabled">فعال کردن فرگمنت</string>
|
||||
|
||||
<string-array name="share_method">
|
||||
<item>QRcode</item>
|
||||
<item>خروجی گرفتن در کلیپ بورد</item>
|
||||
<item>خروجی گرفتن کانفیگ کامل در کلیپ بورد</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="share_method_more">
|
||||
<item>QRcode</item>
|
||||
<item>Export to clipboard</item>
|
||||
<item>Export full configuration to clipboard</item>
|
||||
<item>Edit</item>
|
||||
<item>Delete</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="share_sub_method">
|
||||
<item>QRcode</item>
|
||||
<item>خروجی گرفتن در کلیپ بورد</item>
|
||||
@@ -340,7 +352,7 @@
|
||||
</string-array>
|
||||
|
||||
<string-array name="preset_rulesets">
|
||||
<item>لیست سفید چین</item>
|
||||
<item>لیست سفید چین ( دور زدن سرزمین اصلی )</item>
|
||||
<item>لیست سیاه چین</item>
|
||||
<item>جهانی(GLOBAL)</item>
|
||||
<item>ایران</item>
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
|
||||
<style name="AppThemeDayNight" parent="Theme.AppCompat.DayNight.DarkActionBar">
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimary</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
<item name="android:statusBarColor">@color/colorPrimary</item>
|
||||
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||
<item name="colorControlNormal">@color/colorAccent</item>
|
||||
<item name="android:fitsSystemWindows">true</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
@@ -133,11 +133,11 @@
|
||||
<string name="menu_item_select_all">Выбрать все</string>
|
||||
<string name="msg_enter_keywords">Введите ключевые слова</string>
|
||||
<string name="switch_bypass_apps_mode">Режим обхода</string>
|
||||
<string name="menu_item_select_proxy_app">Автовыбор проксируемых приложений</string>
|
||||
<string name="menu_item_select_proxy_app">Автовыбор приложений</string>
|
||||
<string name="msg_downloading_content">Загрузка данных</string>
|
||||
<string name="menu_item_export_proxy_app">Экспорт в буфер обмена</string>
|
||||
<string name="menu_item_import_proxy_app">Импорт из буфера обмена</string>
|
||||
<string name="per_app_proxy_settings">Настройки выбранных приложений</string>
|
||||
<string name="per_app_proxy_settings">Выбор приложений</string>
|
||||
<string name="per_app_proxy_settings_enable">Использовать выбор приложений</string>
|
||||
|
||||
<!-- Preferences -->
|
||||
@@ -173,7 +173,7 @@
|
||||
<string name="summary_pref_local_dns_enabled">Обслуживание выполняется DNS-модулем ядра (в настройках маршрутизации рекомендуется выбрать режим «Все, кроме LAN и Китая»)</string>
|
||||
|
||||
<string name="title_pref_fake_dns_enabled">Использовать поддельную DNS</string>
|
||||
<string name="summary_pref_fake_dns_enabled">Локальная DNS возвращает поддельный IP-адрес (быстрее, но может не работать с некоторыми приложениями)</string>
|
||||
<string name="summary_pref_fake_dns_enabled">Локальная DNS возвращает поддельные IP-адреса (быстрее, но может не работать с некоторыми приложениями)</string>
|
||||
|
||||
<string name="title_pref_prefer_ipv6">Предпочитать IPv6</string>
|
||||
<string name="summary_pref_prefer_ipv6">Предпочитать IPv6-адреса и маршрутизацию</string>
|
||||
@@ -215,6 +215,9 @@
|
||||
<string name="title_pref_append_http_proxy">Дополнительный HTTP-прокси</string>
|
||||
<string name="summary_pref_append_http_proxy">HTTP-прокси будет использоваться напрямую (из браузера и других поддерживающих приложений), минуя виртуальный сетевой адаптер (Android 10+)</string>
|
||||
|
||||
<string name="title_pref_double_column_display">Enable double column display</string>
|
||||
<string name="summary_pref_double_column_display">The profile list is displayed in double columns, allowing more content to be displayed on the screen. You need to restart the application to take effect.</string>
|
||||
|
||||
<!-- AboutActivity -->
|
||||
<string name="title_pref_feedback">Обратная связь</string>
|
||||
<string name="summary_pref_feedback">Предложить улучшение или сообщить об ошибке на GitHub</string>
|
||||
@@ -324,6 +327,14 @@
|
||||
<item>Экспорт всей конфигурации в буфер обмена</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="share_method_more">
|
||||
<item>QRcode</item>
|
||||
<item>Export to clipboard</item>
|
||||
<item>Export full configuration to clipboard</item>
|
||||
<item>Edit</item>
|
||||
<item>Delete</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="share_sub_method">
|
||||
<item>QR-код</item>
|
||||
<item>Экспорт в буфер обмена</item>
|
||||
|
||||
@@ -216,6 +216,9 @@
|
||||
<string name="title_pref_append_http_proxy">Append HTTP Proxy to VPN</string>
|
||||
<string name="summary_pref_append_http_proxy">HTTP proxy will be used directly from (browser/ some supported apps), without going through the virtual NIC device (Android 10+)</string>
|
||||
|
||||
<string name="title_pref_double_column_display">Enable double column display</string>
|
||||
<string name="summary_pref_double_column_display">The profile list is displayed in double columns, allowing more content to be displayed on the screen. You need to restart the application to take effect.</string>
|
||||
|
||||
<!-- AboutActivity -->
|
||||
<string name="title_pref_feedback">Phản hồi lỗi</string>
|
||||
<string name="summary_pref_feedback">Phản hồi cải tiến hoặc lỗi lên GitHub</string>
|
||||
@@ -312,6 +315,14 @@
|
||||
<item>Sao chép thành cấu hình tùy chỉnh</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="share_method_more">
|
||||
<item>QRcode</item>
|
||||
<item>Export to clipboard</item>
|
||||
<item>Export full configuration to clipboard</item>
|
||||
<item>Edit</item>
|
||||
<item>Delete</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="share_sub_method">
|
||||
<item>Xuất gói ra mã QR (Chụp màn hình để lưu)</item>
|
||||
<item>Xuất gói vào Clipboard</item>
|
||||
|
||||
@@ -213,6 +213,9 @@
|
||||
<string name="title_pref_append_http_proxy">追加 HTTP 代理至 VPN</string>
|
||||
<string name="summary_pref_append_http_proxy">浏览器 / 一些支持的应用 将直接使用 HTTP 代理, 而不经过虚拟网卡设备 (Android 10+)</string>
|
||||
|
||||
<string name="title_pref_double_column_display">启用双列显示</string>
|
||||
<string name="summary_pref_double_column_display">配置文件列表以双列显示,允许在屏幕上显示更多内容。需要重启应用生效。</string>
|
||||
|
||||
<!-- AboutActivity -->
|
||||
<string name="title_pref_feedback">反馈</string>
|
||||
<string name="summary_pref_feedback">反馈改进或漏洞至 GitHub</string>
|
||||
@@ -316,6 +319,14 @@
|
||||
<item>导出完整配置至剪贴板</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="share_method_more">
|
||||
<item>二维码</item>
|
||||
<item>导出至剪贴板</item>
|
||||
<item>导出完整配置至剪贴板</item>
|
||||
<item>编辑</item>
|
||||
<item>删除</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="share_sub_method">
|
||||
<item>二维码</item>
|
||||
<item>导出至剪贴板</item>
|
||||
|
||||
@@ -214,6 +214,9 @@
|
||||
<string name="title_pref_append_http_proxy">追加 HTTP 代理至 VPN</string>
|
||||
<string name="summary_pref_append_http_proxy">瀏覽器 / 一些支援的應用 將直接使用 HTTP 代理, 而不經過虛擬網卡設備 (Android 10+)</string>
|
||||
|
||||
<string name="title_pref_double_column_display">啟用雙列顯示</string>
|
||||
<string name="summary_pref_double_column_display">設定檔清單以雙列顯示,允許在螢幕上顯示更多內容。需要重啟應用生效。</string>
|
||||
|
||||
<!-- AboutActivity -->
|
||||
<string name="title_pref_feedback">意見回饋</string>
|
||||
<string name="summary_pref_feedback">前往 GitHub 回報錯誤</string>
|
||||
@@ -316,6 +319,14 @@
|
||||
<item>匯出完整設定至剪貼簿</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="share_method_more">
|
||||
<item>QR Code</item>
|
||||
<item>匯出至剪貼簿</item>
|
||||
<item>匯出完整設定至剪貼簿</item>
|
||||
<item>編輯</item>
|
||||
<item>刪除</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="share_sub_method">
|
||||
<item>QR Code</item>
|
||||
<item>匯出至剪貼簿</item>
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<dimen name="padding_spacing_dp4">4dp</dimen>
|
||||
<dimen name="padding_spacing_dp8">8dp</dimen>
|
||||
<dimen name="padding_spacing_dp16">16dp</dimen>
|
||||
|
||||
<dimen name="image_size_dp24">24dp</dimen>
|
||||
|
||||
<dimen name="view_height_dp48">48dp</dimen>
|
||||
<dimen name="view_height_dp64">64dp</dimen>
|
||||
<dimen name="view_height_dp72">72dp</dimen>
|
||||
<dimen name="view_height_dp90">90dp</dimen>
|
||||
<dimen name="view_height_dp160">160dp</dimen>
|
||||
</resources>
|
||||
|
||||
@@ -217,6 +217,9 @@
|
||||
<string name="title_pref_append_http_proxy">Append HTTP Proxy to VPN</string>
|
||||
<string name="summary_pref_append_http_proxy">HTTP proxy will be used directly from (browser/ some supported apps), without going through the virtual NIC device (Android 10+)</string>
|
||||
|
||||
<string name="title_pref_double_column_display">Enable double column display</string>
|
||||
<string name="summary_pref_double_column_display">The profile list is displayed in double columns, allowing more content to be displayed on the screen. You need to restart the application to take effect.</string>
|
||||
|
||||
<!-- AboutActivity -->
|
||||
<string name="title_pref_feedback">Feedback</string>
|
||||
<string name="summary_pref_feedback">Feedback enhancements or bugs to GitHub</string>
|
||||
@@ -326,6 +329,14 @@
|
||||
<item>Export full configuration to clipboard</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="share_method_more">
|
||||
<item>QRcode</item>
|
||||
<item>Export to clipboard</item>
|
||||
<item>Export full configuration to clipboard</item>
|
||||
<item>Edit</item>
|
||||
<item>Delete</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="share_sub_method">
|
||||
<item>QRcode</item>
|
||||
<item>Export to clipboard</item>
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
<style name="AppThemeDayNight" parent="Theme.AppCompat.DayNight">
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimary</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
<item name="android:statusBarColor">@color/colorPrimary</item>
|
||||
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||
<item name="colorControlNormal">@color/colorAccent</item>
|
||||
<item name="android:fitsSystemWindows">true</item>
|
||||
</style>
|
||||
|
||||
<style name="AppThemeDayNight.NoActionBar" parent="AppThemeDayNight">
|
||||
|
||||
@@ -75,6 +75,11 @@
|
||||
android:summary="@string/summary_pref_start_scan_immediate"
|
||||
android:title="@string/title_pref_start_scan_immediate" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:key="pref_double_column_display"
|
||||
android:summary="@string/summary_pref_double_column_display"
|
||||
android:title="@string/title_pref_double_column_display" />
|
||||
|
||||
<ListPreference
|
||||
android:defaultValue="auto"
|
||||
android:entries="@array/language_select"
|
||||
|
||||
Reference in New Issue
Block a user