Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bcf5d49a3d | |||
| 4fffb17283 | |||
| 83b8bdfdf4 | |||
| cc1538a24d | |||
| eb19199d18 | |||
| 441e5ef8d5 | |||
| d768774aad | |||
| c3d83907a5 | |||
| b52a98ae5e | |||
| a70e4089e3 |
+60
@@ -1,6 +1,66 @@
|
||||
# Ignore data and key store files
|
||||
*.dat
|
||||
*.jks
|
||||
|
||||
# Ignore output JSON file
|
||||
V2rayNG/app/release/output.json
|
||||
|
||||
# Ignore IDE and build system directories
|
||||
.idea/
|
||||
.gradle/
|
||||
*.iml
|
||||
|
||||
# Ignore local properties and DS_Store files
|
||||
/local.properties
|
||||
.DS_Store
|
||||
|
||||
# Ignore build directories and captures
|
||||
/build
|
||||
/captures
|
||||
V2rayNG/app/build
|
||||
V2rayNG/build
|
||||
V2rayNG/local.properties
|
||||
|
||||
# Ignore APK and AAR files
|
||||
*.apk
|
||||
*.aar
|
||||
|
||||
# Ignore signing properties
|
||||
signing.properties
|
||||
|
||||
# Ignore shared object files
|
||||
*.so
|
||||
|
||||
# Ignore Google services JSON
|
||||
V2rayNG/app/google-services.json
|
||||
|
||||
# Additional common Android/Java ignores
|
||||
*.log
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*.orig
|
||||
*.class
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
|
||||
# Ignore executable files
|
||||
*.exe
|
||||
*.dll
|
||||
*.obj
|
||||
*.o
|
||||
*.pyc
|
||||
*.pyo
|
||||
|
||||
# Ignore files from other IDEs
|
||||
.vscode/
|
||||
.classpath
|
||||
.project
|
||||
.settings/
|
||||
*.sublime-workspace
|
||||
*.sublime-project
|
||||
|
||||
# Ignore OS-specific files
|
||||
Thumbs.db
|
||||
.DS_Store
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
*.apk
|
||||
signing.properties
|
||||
*.aar
|
||||
@@ -1,2 +0,0 @@
|
||||
/build
|
||||
/google-services.json
|
||||
@@ -12,8 +12,8 @@ android {
|
||||
applicationId = "com.v2ray.ang"
|
||||
minSdk = 21
|
||||
targetSdk = 35
|
||||
versionCode = 642
|
||||
versionName = "1.9.42"
|
||||
versionCode = 643
|
||||
versionName = "1.9.43"
|
||||
multiDexEnabled = true
|
||||
|
||||
val abiFilterList = (properties["ABI_FILTERS"] as? String)?.split(';')
|
||||
@@ -82,8 +82,9 @@ android {
|
||||
val isFdroid = variant.productFlavors.any { it.name == "fdroid" }
|
||||
if (isFdroid) {
|
||||
val versionCodes =
|
||||
mapOf("armeabi-v7a" to 2, "arm64-v8a" to 1, "x86" to 4, "x86_64" to 3, "universal" to 0
|
||||
)
|
||||
mapOf(
|
||||
"armeabi-v7a" to 2, "arm64-v8a" to 1, "x86" to 4, "x86_64" to 3, "universal" to 0
|
||||
)
|
||||
|
||||
variant.outputs
|
||||
.map { it as com.android.build.gradle.internal.api.ApkVariantOutputImpl }
|
||||
@@ -148,7 +149,7 @@ dependencies {
|
||||
|
||||
// UI Libraries
|
||||
implementation(libs.material)
|
||||
implementation(libs.toastcompat)
|
||||
implementation(libs.toasty)
|
||||
implementation(libs.editorkit)
|
||||
implementation(libs.flexbox)
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<!-- <useapplications-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> -->
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission
|
||||
@@ -52,10 +51,10 @@
|
||||
android:banner="@mipmap/ic_banner"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppThemeDayNight"
|
||||
android:usesCleartextTraffic="true"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
tools:targetApi="m">
|
||||
|
||||
<activity
|
||||
@@ -213,7 +212,8 @@
|
||||
android:icon="@drawable/ic_stat_name"
|
||||
android:label="@string/app_tile_name"
|
||||
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"
|
||||
android:process=":RunSoLibV2RayDaemon">
|
||||
android:process=":RunSoLibV2RayDaemon"
|
||||
tools:targetApi="24">
|
||||
<intent-filter>
|
||||
<action android:name="android.service.quicksettings.action.QS_TILE" />
|
||||
</intent-filter>
|
||||
|
||||
@@ -169,7 +169,7 @@ object AppConfig {
|
||||
const val DNS_QUAD9_DOMAIN = "dns.quad9.net"
|
||||
const val DNS_YANDEX_DOMAIN = "common.dot.dns.yandex.net"
|
||||
|
||||
|
||||
|
||||
val DNS_ALIDNS_ADDRESSES = arrayListOf("223.5.5.5", "223.6.6.6", "2400:3200::1", "2400:3200:baba::1")
|
||||
val DNS_CLOUDFLARE_ADDRESSES = arrayListOf("1.1.1.1", "1.0.0.1", "2606:4700:4700::1111", "2606:4700:4700::1001")
|
||||
val DNS_DNSPOD_ADDRESSES = arrayListOf("1.12.12.12", "120.53.53.53")
|
||||
|
||||
@@ -11,7 +11,8 @@ enum class EConfigType(val value: Int, val protocolScheme: String) {
|
||||
VLESS(5, AppConfig.VLESS),
|
||||
TROJAN(6, AppConfig.TROJAN),
|
||||
WIREGUARD(7, AppConfig.WIREGUARD),
|
||||
// TUIC(8, AppConfig.TUIC),
|
||||
|
||||
// TUIC(8, AppConfig.TUIC),
|
||||
HYSTERIA2(9, AppConfig.HYSTERIA2),
|
||||
HTTP(10, AppConfig.HTTP);
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ enum class NetworkType(val type: String) {
|
||||
XHTTP("xhttp"),
|
||||
HTTP("http"),
|
||||
H2("h2"),
|
||||
|
||||
//QUIC("quic"),
|
||||
GRPC("grpc");
|
||||
|
||||
|
||||
@@ -261,7 +261,8 @@ data class V2rayConfig(
|
||||
) {
|
||||
data class HeaderBean(
|
||||
var type: String = "none",
|
||||
var domain: String? = null)
|
||||
var domain: String? = null
|
||||
)
|
||||
}
|
||||
|
||||
data class WsSettingsBean(
|
||||
|
||||
@@ -8,7 +8,7 @@ import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.widget.Toast
|
||||
import com.v2ray.ang.AngApplication
|
||||
import me.drakeet.support.toast.ToastCompat
|
||||
import es.dmoral.toasty.Toasty
|
||||
import org.json.JSONObject
|
||||
import java.io.Serializable
|
||||
import java.net.URI
|
||||
@@ -23,7 +23,7 @@ val Context.v2RayApplication: AngApplication?
|
||||
* @param message The resource ID of the message to show.
|
||||
*/
|
||||
fun Context.toast(message: Int) {
|
||||
ToastCompat.makeText(this, message, Toast.LENGTH_SHORT).show()
|
||||
Toasty.normal(this, message).show()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -32,9 +32,46 @@ fun Context.toast(message: Int) {
|
||||
* @param message The text of the message to show.
|
||||
*/
|
||||
fun Context.toast(message: CharSequence) {
|
||||
ToastCompat.makeText(this, message, Toast.LENGTH_SHORT).show()
|
||||
Toasty.normal(this, message).show()
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a toast message with the given resource ID.
|
||||
*
|
||||
* @param message The resource ID of the message to show.
|
||||
*/
|
||||
fun Context.toastSuccess(message: Int) {
|
||||
Toasty.success(this, message, Toast.LENGTH_SHORT, true).show()
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a toast message with the given text.
|
||||
*
|
||||
* @param message The text of the message to show.
|
||||
*/
|
||||
fun Context.toastSuccess(message: CharSequence) {
|
||||
Toasty.success(this, message, Toast.LENGTH_SHORT, true).show()
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a toast message with the given resource ID.
|
||||
*
|
||||
* @param message The resource ID of the message to show.
|
||||
*/
|
||||
fun Context.toastError(message: Int) {
|
||||
Toasty.error(this, message, Toast.LENGTH_SHORT, true).show()
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a toast message with the given text.
|
||||
*
|
||||
* @param message The text of the message to show.
|
||||
*/
|
||||
fun Context.toastError(message: CharSequence) {
|
||||
Toasty.error(this, message, Toast.LENGTH_SHORT, true).show()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Puts a key-value pair into the JSONObject.
|
||||
*
|
||||
|
||||
@@ -120,7 +120,7 @@ open class FmtBase {
|
||||
config.path.let { if (it.isNotNullEmpty()) dicQuery["path"] = it.orEmpty() }
|
||||
}
|
||||
|
||||
NetworkType.XHTTP -> {
|
||||
NetworkType.XHTTP -> {
|
||||
config.host.let { if (it.isNotNullEmpty()) dicQuery["host"] = it.orEmpty() }
|
||||
config.path.let { if (it.isNotNullEmpty()) dicQuery["path"] = it.orEmpty() }
|
||||
config.xhttpMode.let { if (it.isNotNullEmpty()) dicQuery["mode"] = it.orEmpty() }
|
||||
|
||||
@@ -73,6 +73,7 @@ object VmessFmt : FmtBase() {
|
||||
config.serviceName = vmessQRCode.path
|
||||
config.authority = vmessQRCode.host
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
|
||||
@@ -119,6 +120,7 @@ object VmessFmt : FmtBase() {
|
||||
vmessQRCode.path = config.serviceName.orEmpty()
|
||||
vmessQRCode.host = config.authority.orEmpty()
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
|
||||
|
||||
@@ -172,7 +172,7 @@ object MigrateManager {
|
||||
|
||||
outbound.settings?.let { wireguard ->
|
||||
config.secretKey = wireguard.secretKey
|
||||
config.localAddress = (wireguard.address as List<*>).joinToString(",").removeWhiteSpace().toString()
|
||||
config.localAddress = (wireguard.address as List<*>).joinToString(",").removeWhiteSpace().toString()
|
||||
config.publicKey = wireguard.peers?.getOrNull(0)?.publicKey
|
||||
config.mtu = wireguard.mtu
|
||||
config.reserved = wireguard.reserved?.joinToString(",").removeWhiteSpace().toString()
|
||||
|
||||
@@ -459,7 +459,7 @@ object V2rayConfigManager {
|
||||
outbound.mux?.enabled = true
|
||||
outbound.mux?.concurrency = MmkvManager.decodeSettingsString(AppConfig.PREF_MUX_CONCURRENCY, "8").orEmpty().toInt()
|
||||
outbound.mux?.xudpConcurrency = MmkvManager.decodeSettingsString(AppConfig.PREF_MUX_XUDP_CONCURRENCY, "16").orEmpty().toInt()
|
||||
outbound.mux?.xudpProxyUDP443 = MmkvManager.decodeSettingsString(AppConfig.PREF_MUX_XUDP_QUIC,"reject")
|
||||
outbound.mux?.xudpProxyUDP443 = MmkvManager.decodeSettingsString(AppConfig.PREF_MUX_XUDP_QUIC, "reject")
|
||||
if (protocol.equals(EConfigType.VLESS.name, true) && outbound.settings?.vnext?.first()?.users?.first()?.flow?.isNotEmpty() == true) {
|
||||
outbound.mux?.concurrency = -1
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@ 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.extension.toastError
|
||||
import com.v2ray.ang.extension.toastSuccess
|
||||
import com.v2ray.ang.handler.SpeedtestManager
|
||||
import com.v2ray.ang.util.Utils
|
||||
import com.v2ray.ang.util.ZipUtil
|
||||
@@ -50,9 +52,9 @@ class AboutActivity : BaseActivity() {
|
||||
binding.layoutBackup.setOnClickListener {
|
||||
val ret = backupConfiguration(extDir.absolutePath)
|
||||
if (ret.first) {
|
||||
toast(R.string.toast_success)
|
||||
toastSuccess(R.string.toast_success)
|
||||
} else {
|
||||
toast(R.string.toast_failure)
|
||||
toastError(R.string.toast_failure)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +74,7 @@ class AboutActivity : BaseActivity() {
|
||||
)
|
||||
)
|
||||
} else {
|
||||
toast(R.string.toast_failure)
|
||||
toastError(R.string.toast_failure)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,7 +128,7 @@ class AboutActivity : BaseActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
fun backupConfiguration(outputZipFilePos: String): Pair<Boolean, String> {
|
||||
private fun backupConfiguration(outputZipFilePos: String): Pair<Boolean, String> {
|
||||
val dateFormated = SimpleDateFormat(
|
||||
"yyyy-MM-dd-HH-mm-ss",
|
||||
Locale.getDefault()
|
||||
@@ -147,7 +149,7 @@ class AboutActivity : BaseActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
fun restoreConfiguration(zipFile: File): Boolean {
|
||||
private fun restoreConfiguration(zipFile: File): Boolean {
|
||||
val backupDir = this.cacheDir.absolutePath + "/${System.currentTimeMillis()}"
|
||||
|
||||
if (!ZipUtil.unzipToFolder(zipFile, backupDir)) {
|
||||
@@ -185,13 +187,13 @@ class AboutActivity : BaseActivity() {
|
||||
}
|
||||
}
|
||||
if (restoreConfiguration(targetFile)) {
|
||||
toast(R.string.toast_success)
|
||||
toastSuccess(R.string.toast_success)
|
||||
} else {
|
||||
toast(R.string.toast_failure)
|
||||
toastError(R.string.toast_failure)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(AppConfig.ANG_PACKAGE, "Error during file restore: ${e.message}", e)
|
||||
toast(R.string.toast_failure)
|
||||
toastError(R.string.toast_failure)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.v2ray.ang.ui
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
@@ -10,7 +11,7 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
import com.v2ray.ang.AppConfig.ANG_PACKAGE
|
||||
import com.v2ray.ang.R
|
||||
import com.v2ray.ang.databinding.ActivityLogcatBinding
|
||||
import com.v2ray.ang.extension.toast
|
||||
import com.v2ray.ang.extension.toastSuccess
|
||||
import com.v2ray.ang.util.Utils
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -21,7 +22,7 @@ import java.io.IOException
|
||||
class LogcatActivity : BaseActivity(), SwipeRefreshLayout.OnRefreshListener {
|
||||
private val binding by lazy { ActivityLogcatBinding.inflate(layoutInflater) }
|
||||
|
||||
var logsetsAll: MutableList<String> = mutableListOf()
|
||||
private var logsetsAll: MutableList<String> = mutableListOf()
|
||||
var logsets: MutableList<String> = mutableListOf()
|
||||
private val adapter by lazy { LogcatRecyclerAdapter(this) }
|
||||
|
||||
@@ -62,7 +63,7 @@ class LogcatActivity : BaseActivity(), SwipeRefreshLayout.OnRefreshListener {
|
||||
launch(Dispatchers.Main) {
|
||||
logsetsAll = allText.toMutableList()
|
||||
logsets = allText.toMutableList()
|
||||
adapter.notifyDataSetChanged()
|
||||
refreshData()
|
||||
binding.refreshLayout.isRefreshing = false
|
||||
}
|
||||
}
|
||||
@@ -84,7 +85,7 @@ class LogcatActivity : BaseActivity(), SwipeRefreshLayout.OnRefreshListener {
|
||||
launch(Dispatchers.Main) {
|
||||
logsetsAll.clear()
|
||||
logsets.clear()
|
||||
adapter.notifyDataSetChanged()
|
||||
refreshData()
|
||||
}
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
@@ -118,7 +119,7 @@ class LogcatActivity : BaseActivity(), SwipeRefreshLayout.OnRefreshListener {
|
||||
override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
|
||||
R.id.copy_all -> {
|
||||
Utils.setClipboard(this, logsets.joinToString("\n"))
|
||||
toast(R.string.toast_success)
|
||||
toastSuccess(R.string.toast_success)
|
||||
true
|
||||
}
|
||||
|
||||
@@ -138,11 +139,16 @@ class LogcatActivity : BaseActivity(), SwipeRefreshLayout.OnRefreshListener {
|
||||
logsetsAll.filter { it.contains(key) }.toMutableList()
|
||||
}
|
||||
|
||||
adapter?.notifyDataSetChanged()
|
||||
refreshData()
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onRefresh() {
|
||||
getLogcat()
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
fun refreshData() {
|
||||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.v2ray.ang.ui
|
||||
|
||||
import android.Manifest
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.res.ColorStateList
|
||||
@@ -31,6 +32,7 @@ import com.v2ray.ang.R
|
||||
import com.v2ray.ang.databinding.ActivityMainBinding
|
||||
import com.v2ray.ang.dto.EConfigType
|
||||
import com.v2ray.ang.extension.toast
|
||||
import com.v2ray.ang.extension.toastError
|
||||
import com.v2ray.ang.handler.AngConfigManager
|
||||
import com.v2ray.ang.handler.MigrateManager
|
||||
import com.v2ray.ang.handler.MmkvManager
|
||||
@@ -204,6 +206,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
|
||||
})
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
private fun setupViewModel() {
|
||||
mainViewModel.updateListAction.observe(this) { index ->
|
||||
if (index >= 0) {
|
||||
@@ -269,7 +272,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
|
||||
binding.tabGroup.isVisible = true
|
||||
}
|
||||
|
||||
fun startV2Ray() {
|
||||
private fun startV2Ray() {
|
||||
if (MmkvManager.getSelectServer().isNullOrEmpty()) {
|
||||
toast(R.string.title_file_chooser)
|
||||
return
|
||||
@@ -277,7 +280,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
|
||||
V2RayServiceManager.startVService(this)
|
||||
}
|
||||
|
||||
fun restartV2Ray() {
|
||||
private fun restartV2Ray() {
|
||||
if (mainViewModel.isRunning.value == true) {
|
||||
V2RayServiceManager.stopVService(this)
|
||||
}
|
||||
@@ -503,13 +506,13 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
|
||||
}
|
||||
|
||||
countSub > 0 -> initGroupTab()
|
||||
else -> toast(R.string.toast_failure)
|
||||
else -> toastError(R.string.toast_failure)
|
||||
}
|
||||
binding.pbWaiting.hide()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
withContext(Dispatchers.Main) {
|
||||
toast(R.string.toast_failure)
|
||||
toastError(R.string.toast_failure)
|
||||
binding.pbWaiting.hide()
|
||||
}
|
||||
e.printStackTrace()
|
||||
@@ -613,7 +616,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
|
||||
toast(getString(R.string.title_update_config_count, count))
|
||||
mainViewModel.reloadServerList()
|
||||
} else {
|
||||
toast(R.string.toast_failure)
|
||||
toastError(R.string.toast_failure)
|
||||
}
|
||||
binding.pbWaiting.hide()
|
||||
}
|
||||
@@ -629,7 +632,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
|
||||
if (ret > 0)
|
||||
toast(getString(R.string.title_export_config_count, ret))
|
||||
else
|
||||
toast(R.string.toast_failure)
|
||||
toastError(R.string.toast_failure)
|
||||
binding.pbWaiting.hide()
|
||||
}
|
||||
}
|
||||
@@ -759,9 +762,9 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
|
||||
// }
|
||||
// if (mainViewModel.appendCustomConfigServer(server)) {
|
||||
// mainViewModel.reloadServerList()
|
||||
// toast(R.string.toast_success)
|
||||
// toastSuccess(R.string.toast_success)
|
||||
// } else {
|
||||
// toast(R.string.toast_failure)
|
||||
// toastError(R.string.toast_failure)
|
||||
// }
|
||||
// //adapter.notifyItemInserted(mainViewModel.serverList.lastIndex)
|
||||
// } catch (e: Exception) {
|
||||
@@ -797,13 +800,13 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
|
||||
// Handle navigation view item clicks here.
|
||||
when (item.itemId) {
|
||||
R.id.sub_setting -> requestSubSettingActivity.launch(Intent(this, SubSettingActivity::class.java))
|
||||
R.id.per_app_proxy_settings -> startActivity(Intent(this, PerAppProxyActivity::class.java))
|
||||
R.id.routing_setting -> requestSubSettingActivity.launch(Intent(this, RoutingSettingActivity::class.java))
|
||||
R.id.user_asset_setting -> startActivity(Intent(this, UserAssetActivity::class.java))
|
||||
R.id.settings -> startActivity(
|
||||
Intent(this, SettingsActivity::class.java)
|
||||
.putExtra("isRunning", mainViewModel.isRunning.value == true)
|
||||
)
|
||||
|
||||
R.id.per_app_proxy_settings -> startActivity(Intent(this, PerAppProxyActivity::class.java))
|
||||
R.id.routing_setting -> requestSubSettingActivity.launch(Intent(this, RoutingSettingActivity::class.java))
|
||||
R.id.promotion -> Utils.openUri(this, "${Utils.decode(AppConfig.PromotionUrl)}?t=${System.currentTimeMillis()}")
|
||||
R.id.logcat -> startActivity(Intent(this, LogcatActivity::class.java))
|
||||
R.id.about -> startActivity(Intent(this, AboutActivity::class.java))
|
||||
|
||||
@@ -19,6 +19,8 @@ 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.extension.toastError
|
||||
import com.v2ray.ang.extension.toastSuccess
|
||||
import com.v2ray.ang.handler.AngConfigManager
|
||||
import com.v2ray.ang.handler.MmkvManager
|
||||
import com.v2ray.ang.helper.ItemTouchHelperAdapter
|
||||
@@ -43,6 +45,10 @@ class MainRecyclerAdapter(val activity: MainActivity) : RecyclerView.Adapter<Mai
|
||||
var isRunning = false
|
||||
private val doubleColumnDisplay = MmkvManager.decodeSettingsBool(AppConfig.PREF_DOUBLE_COLUMN_DISPLAY, false)
|
||||
|
||||
/**
|
||||
* Gets the total number of items in the adapter (servers count + footer view)
|
||||
* @return The total item count
|
||||
*/
|
||||
override fun getItemCount() = mActivity.mainViewModel.serversCache.size + 1
|
||||
|
||||
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
|
||||
@@ -128,6 +134,12 @@ class MainRecyclerAdapter(val activity: MainActivity) : RecyclerView.Adapter<Mai
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the server address information
|
||||
* Hides part of IP or domain information for privacy protection
|
||||
* @param profile The server configuration
|
||||
* @return Formatted address string
|
||||
*/
|
||||
private fun getAddress(profile: ProfileItem): String {
|
||||
// Hide xxx:xxx:***/xxx.xxx.xxx.***
|
||||
return "${
|
||||
@@ -140,6 +152,11 @@ class MainRecyclerAdapter(val activity: MainActivity) : RecyclerView.Adapter<Mai
|
||||
} : ${profile.serverPort}"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the subscription remarks information
|
||||
* @param profile The server configuration
|
||||
* @return Subscription remarks string, or empty string if none
|
||||
*/
|
||||
private fun getSubscriptionRemarks(profile: ProfileItem): String {
|
||||
val subRemarks =
|
||||
if (mActivity.mainViewModel.subscriptionId.isEmpty())
|
||||
@@ -149,6 +166,15 @@ class MainRecyclerAdapter(val activity: MainActivity) : RecyclerView.Adapter<Mai
|
||||
return subRemarks?.toString() ?: ""
|
||||
}
|
||||
|
||||
/**
|
||||
* Shares server configuration
|
||||
* Displays a dialog with sharing options and executes the selected action
|
||||
* @param guid The server unique identifier
|
||||
* @param profile The server configuration
|
||||
* @param position The position in the list
|
||||
* @param shareOptions The list of share options
|
||||
* @param skip The number of options to skip
|
||||
*/
|
||||
private fun shareServer(guid: String, profile: ProfileItem, position: Int, shareOptions: List<String>, skip: Int) {
|
||||
AlertDialog.Builder(mActivity).setItems(shareOptions.toTypedArray()) { _, i ->
|
||||
try {
|
||||
@@ -166,28 +192,46 @@ class MainRecyclerAdapter(val activity: MainActivity) : RecyclerView.Adapter<Mai
|
||||
}.show()
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays QR code for the server configuration
|
||||
* @param guid The server unique identifier
|
||||
*/
|
||||
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()
|
||||
}
|
||||
|
||||
/**
|
||||
* Shares server configuration to clipboard
|
||||
* @param guid The server unique identifier
|
||||
*/
|
||||
private fun share2Clipboard(guid: String) {
|
||||
if (AngConfigManager.share2Clipboard(mActivity, guid) == 0) {
|
||||
mActivity.toast(R.string.toast_success)
|
||||
mActivity.toastSuccess(R.string.toast_success)
|
||||
} else {
|
||||
mActivity.toast(R.string.toast_failure)
|
||||
mActivity.toastError(R.string.toast_failure)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shares full server configuration content to clipboard
|
||||
* @param guid The server unique identifier
|
||||
*/
|
||||
private fun shareFullContent(guid: String) {
|
||||
if (AngConfigManager.shareFullContent2Clipboard(mActivity, guid) == 0) {
|
||||
mActivity.toast(R.string.toast_success)
|
||||
mActivity.toastSuccess(R.string.toast_success)
|
||||
} else {
|
||||
mActivity.toast(R.string.toast_failure)
|
||||
mActivity.toastError(R.string.toast_failure)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Edits server configuration
|
||||
* Opens appropriate editing interface based on configuration type
|
||||
* @param guid The server unique identifier
|
||||
* @param profile The server configuration
|
||||
*/
|
||||
private fun editServer(guid: String, profile: ProfileItem) {
|
||||
val intent = Intent().putExtra("guid", guid)
|
||||
.putExtra("isRunning", isRunning)
|
||||
@@ -199,6 +243,12 @@ class MainRecyclerAdapter(val activity: MainActivity) : RecyclerView.Adapter<Mai
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes server configuration
|
||||
* Handles confirmation dialog and related checks
|
||||
* @param guid The server unique identifier
|
||||
* @param position The position in the list
|
||||
*/
|
||||
private fun removeServer(guid: String, position: Int) {
|
||||
if (guid != MmkvManager.getSelectServer()) {
|
||||
if (MmkvManager.decodeSettingsBool(AppConfig.PREF_CONFIRM_REMOVE) == true) {
|
||||
@@ -218,12 +268,22 @@ class MainRecyclerAdapter(val activity: MainActivity) : RecyclerView.Adapter<Mai
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the actual server removal process
|
||||
* @param guid The server unique identifier
|
||||
* @param position The position in the list
|
||||
*/
|
||||
private fun removeServerSub(guid: String, position: Int) {
|
||||
mActivity.mainViewModel.removeServer(guid)
|
||||
notifyItemRemoved(position)
|
||||
notifyItemRangeChanged(position, mActivity.mainViewModel.serversCache.size)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the selected server
|
||||
* Updates UI and restarts service if needed
|
||||
* @param guid The server unique identifier to select
|
||||
*/
|
||||
private fun setSelectServer(guid: String) {
|
||||
val selected = MmkvManager.getSelectServer()
|
||||
if (guid != selected) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.v2ray.ang.ui
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
@@ -13,6 +14,7 @@ import com.v2ray.ang.R
|
||||
import com.v2ray.ang.databinding.ActivityBypassListBinding
|
||||
import com.v2ray.ang.dto.AppInfo
|
||||
import com.v2ray.ang.extension.toast
|
||||
import com.v2ray.ang.extension.toastSuccess
|
||||
import com.v2ray.ang.extension.v2RayApplication
|
||||
import com.v2ray.ang.handler.MmkvManager
|
||||
import com.v2ray.ang.handler.SettingsManager
|
||||
@@ -51,13 +53,13 @@ class PerAppProxyActivity : BaseActivity() {
|
||||
appsList.forEach { app ->
|
||||
app.isSelected = if (blacklist.contains(app.packageName)) 1 else 0
|
||||
}
|
||||
appsList.sortedWith(Comparator { p1, p2 ->
|
||||
appsList.sortedWith { p1, p2 ->
|
||||
when {
|
||||
p1.isSelected > p2.isSelected -> -1
|
||||
p1.isSelected == p2.isSelected -> 0
|
||||
else -> 1
|
||||
}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
val collator = Collator.getInstance()
|
||||
appsList.sortedWith(compareBy(collator) { it.appName })
|
||||
@@ -112,8 +114,10 @@ class PerAppProxyActivity : BaseActivity() {
|
||||
return super.onCreateOptionsMenu(menu)
|
||||
}
|
||||
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
|
||||
R.id.select_all -> adapter?.let {
|
||||
R.id.select_all -> adapter?.let { it ->
|
||||
val pkgNames = it.apps.map { it.packageName }
|
||||
if (it.blacklist.containsAll(pkgNames)) {
|
||||
it.apps.forEach {
|
||||
@@ -162,7 +166,7 @@ class PerAppProxyActivity : BaseActivity() {
|
||||
launch(Dispatchers.Main) {
|
||||
Log.d(ANG_PACKAGE, content)
|
||||
selectProxyApp(content, true)
|
||||
toast(R.string.toast_success)
|
||||
toastSuccess(R.string.toast_success)
|
||||
binding.pbWaiting.hide()
|
||||
}
|
||||
}
|
||||
@@ -172,7 +176,7 @@ class PerAppProxyActivity : BaseActivity() {
|
||||
val content = Utils.getClipboard(applicationContext)
|
||||
if (TextUtils.isEmpty(content)) return
|
||||
selectProxyApp(content, false)
|
||||
toast(R.string.toast_success)
|
||||
toastSuccess(R.string.toast_success)
|
||||
}
|
||||
|
||||
private fun exportProxyApp() {
|
||||
@@ -182,9 +186,10 @@ class PerAppProxyActivity : BaseActivity() {
|
||||
lst = lst + System.getProperty("line.separator") + it
|
||||
}
|
||||
Utils.setClipboard(applicationContext, lst)
|
||||
toast(R.string.toast_success)
|
||||
toastSuccess(R.string.toast_success)
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
private fun selectProxyApp(content: String, force: Boolean): Boolean {
|
||||
try {
|
||||
val proxyApps = if (TextUtils.isEmpty(content)) {
|
||||
@@ -197,7 +202,7 @@ class PerAppProxyActivity : BaseActivity() {
|
||||
adapter?.blacklist?.clear()
|
||||
|
||||
if (binding.switchBypassApps.isChecked) {
|
||||
adapter?.let {
|
||||
adapter?.let { it ->
|
||||
it.apps.forEach block@{
|
||||
val packageName = it.packageName
|
||||
Log.d(ANG_PACKAGE, packageName)
|
||||
@@ -210,7 +215,7 @@ class PerAppProxyActivity : BaseActivity() {
|
||||
it.notifyDataSetChanged()
|
||||
}
|
||||
} else {
|
||||
adapter?.let {
|
||||
adapter?.let { it ->
|
||||
it.apps.forEach block@{
|
||||
val packageName = it.packageName
|
||||
Log.d(ANG_PACKAGE, packageName)
|
||||
@@ -259,7 +264,12 @@ class PerAppProxyActivity : BaseActivity() {
|
||||
|
||||
adapter = PerAppProxyAdapter(this, apps, adapter?.blacklist)
|
||||
binding.recyclerView.adapter = adapter
|
||||
adapter?.notifyDataSetChanged()
|
||||
refreshData()
|
||||
return true
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
fun refreshData() {
|
||||
adapter?.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.v2ray.ang.R
|
||||
import com.v2ray.ang.databinding.ActivityRoutingEditBinding
|
||||
import com.v2ray.ang.dto.RulesetItem
|
||||
import com.v2ray.ang.extension.toast
|
||||
import com.v2ray.ang.extension.toastSuccess
|
||||
import com.v2ray.ang.handler.SettingsManager
|
||||
import com.v2ray.ang.util.Utils
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -78,7 +79,7 @@ class RoutingEditActivity : BaseActivity() {
|
||||
}
|
||||
|
||||
SettingsManager.saveRoutingRuleset(position, rulesetItem)
|
||||
toast(R.string.toast_success)
|
||||
toastSuccess(R.string.toast_success)
|
||||
finish()
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.v2ray.ang.ui
|
||||
|
||||
import android.Manifest
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
@@ -17,6 +18,8 @@ import com.v2ray.ang.R
|
||||
import com.v2ray.ang.databinding.ActivityRoutingSettingBinding
|
||||
import com.v2ray.ang.dto.RulesetItem
|
||||
import com.v2ray.ang.extension.toast
|
||||
import com.v2ray.ang.extension.toastError
|
||||
import com.v2ray.ang.extension.toastSuccess
|
||||
import com.v2ray.ang.handler.MmkvManager
|
||||
import com.v2ray.ang.handler.SettingsManager
|
||||
import com.v2ray.ang.helper.SimpleItemTouchHelperCallback
|
||||
@@ -87,7 +90,6 @@ class RoutingSettingActivity : BaseActivity() {
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean = when (item.itemId) {
|
||||
R.id.add_rule -> startActivity(Intent(this, RoutingEditActivity::class.java)).let { true }
|
||||
R.id.user_asset_setting -> startActivity(Intent(this, UserAssetActivity::class.java)).let { true }
|
||||
R.id.import_predefined_rulesets -> importPredefined().let { true }
|
||||
R.id.import_rulesets_from_clipboard -> importFromClipboard().let { true }
|
||||
R.id.import_rulesets_from_qrcode -> requestCameraPermissionLauncher.launch(Manifest.permission.CAMERA).let { true }
|
||||
@@ -104,7 +106,7 @@ class RoutingSettingActivity : BaseActivity() {
|
||||
SettingsManager.resetRoutingRulesetsFromPresets(this@RoutingSettingActivity, i)
|
||||
launch(Dispatchers.Main) {
|
||||
refreshData()
|
||||
toast(R.string.toast_success)
|
||||
toastSuccess(R.string.toast_success)
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
@@ -125,7 +127,7 @@ class RoutingSettingActivity : BaseActivity() {
|
||||
Utils.getClipboard(this)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
toast(R.string.toast_failure)
|
||||
toastError(R.string.toast_failure)
|
||||
return@setPositiveButton
|
||||
}
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
@@ -133,9 +135,9 @@ class RoutingSettingActivity : BaseActivity() {
|
||||
withContext(Dispatchers.Main) {
|
||||
if (result) {
|
||||
refreshData()
|
||||
toast(R.string.toast_success)
|
||||
toastSuccess(R.string.toast_success)
|
||||
} else {
|
||||
toast(R.string.toast_failure)
|
||||
toastError(R.string.toast_failure)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -149,10 +151,10 @@ class RoutingSettingActivity : BaseActivity() {
|
||||
private fun export2Clipboard() {
|
||||
val rulesetList = MmkvManager.decodeRoutingRulesets()
|
||||
if (rulesetList.isNullOrEmpty()) {
|
||||
toast(R.string.toast_failure)
|
||||
toastError(R.string.toast_failure)
|
||||
} else {
|
||||
Utils.setClipboard(this, JsonUtil.toJson(rulesetList))
|
||||
toast(R.string.toast_success)
|
||||
toastSuccess(R.string.toast_success)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,9 +172,9 @@ class RoutingSettingActivity : BaseActivity() {
|
||||
withContext(Dispatchers.Main) {
|
||||
if (result) {
|
||||
refreshData()
|
||||
toast(R.string.toast_success)
|
||||
toastSuccess(R.string.toast_success)
|
||||
} else {
|
||||
toast(R.string.toast_failure)
|
||||
toastError(R.string.toast_failure)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -184,6 +186,7 @@ class RoutingSettingActivity : BaseActivity() {
|
||||
return true
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
fun refreshData() {
|
||||
rulesets.clear()
|
||||
rulesets.addAll(MmkvManager.decodeRoutingRulesets() ?: mutableListOf())
|
||||
|
||||
@@ -6,6 +6,8 @@ import android.os.Bundle
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import com.v2ray.ang.R
|
||||
import com.v2ray.ang.extension.toast
|
||||
import com.v2ray.ang.extension.toastError
|
||||
import com.v2ray.ang.extension.toastSuccess
|
||||
import com.v2ray.ang.handler.AngConfigManager
|
||||
|
||||
class ScScannerActivity : BaseActivity() {
|
||||
@@ -27,7 +29,7 @@ class ScScannerActivity : BaseActivity() {
|
||||
importQRcode()
|
||||
}
|
||||
|
||||
fun importQRcode(): Boolean {
|
||||
private fun importQRcode(): Boolean {
|
||||
requestCameraPermissionLauncher.launch(Manifest.permission.CAMERA)
|
||||
return true
|
||||
}
|
||||
@@ -38,9 +40,9 @@ class ScScannerActivity : BaseActivity() {
|
||||
val (count, countSub) = AngConfigManager.importBatchConfig(scanResult, "", false)
|
||||
|
||||
if (count + countSub > 0) {
|
||||
toast(R.string.toast_success)
|
||||
toastSuccess(R.string.toast_success)
|
||||
} else {
|
||||
toast(R.string.toast_failure)
|
||||
toastError(R.string.toast_failure)
|
||||
}
|
||||
|
||||
startActivity(Intent(this, MainActivity::class.java))
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.v2ray.ang.dto.NetworkType
|
||||
import com.v2ray.ang.dto.ProfileItem
|
||||
import com.v2ray.ang.extension.isNotNullEmpty
|
||||
import com.v2ray.ang.extension.toast
|
||||
import com.v2ray.ang.extension.toastSuccess
|
||||
import com.v2ray.ang.handler.MmkvManager
|
||||
import com.v2ray.ang.util.JsonUtil
|
||||
import com.v2ray.ang.util.Utils
|
||||
@@ -354,11 +355,11 @@ class ServerActivity : BaseActivity() {
|
||||
container_alpn?.visibility = View.VISIBLE
|
||||
|
||||
et_sni?.text = Utils.getEditable(config.sni)
|
||||
config.fingerPrint?.let {
|
||||
config.fingerPrint?.let { it ->
|
||||
val utlsIndex = Utils.arrayFind(uTlsItems, it)
|
||||
utlsIndex.let { sp_stream_fingerprint?.setSelection(if (it >= 0) it else 0) }
|
||||
}
|
||||
config.alpn?.let {
|
||||
config.alpn?.let { it ->
|
||||
val alpnIndex = Utils.arrayFind(alpns, it)
|
||||
alpnIndex.let { sp_stream_alpn?.setSelection(if (it >= 0) it else 0) }
|
||||
}
|
||||
@@ -482,7 +483,7 @@ class ServerActivity : BaseActivity() {
|
||||
}
|
||||
Log.d(ANG_PACKAGE, JsonUtil.toJsonPretty(config) ?: "")
|
||||
MmkvManager.encodeServerConfig(editGuid, config)
|
||||
toast(R.string.toast_success)
|
||||
toastSuccess(R.string.toast_success)
|
||||
finish()
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import com.blacksquircle.ui.editorkit.utils.EditorTheme
|
||||
import com.blacksquircle.ui.language.json.JsonLanguage
|
||||
@@ -13,10 +12,10 @@ import com.v2ray.ang.databinding.ActivityServerCustomConfigBinding
|
||||
import com.v2ray.ang.dto.EConfigType
|
||||
import com.v2ray.ang.dto.ProfileItem
|
||||
import com.v2ray.ang.extension.toast
|
||||
import com.v2ray.ang.extension.toastSuccess
|
||||
import com.v2ray.ang.fmt.CustomFmt
|
||||
import com.v2ray.ang.handler.MmkvManager
|
||||
import com.v2ray.ang.util.Utils
|
||||
import me.drakeet.support.toast.ToastCompat
|
||||
|
||||
class ServerCustomConfigActivity : BaseActivity() {
|
||||
private val binding by lazy { ActivityServerCustomConfigBinding.inflate(layoutInflater) }
|
||||
@@ -91,7 +90,7 @@ class ServerCustomConfigActivity : BaseActivity() {
|
||||
|
||||
MmkvManager.encodeServerConfig(editGuid, config)
|
||||
MmkvManager.encodeServerRaw(editGuid, binding.editor.text.toString())
|
||||
toast(R.string.toast_success)
|
||||
toastSuccess(R.string.toast_success)
|
||||
finish()
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import com.v2ray.ang.R
|
||||
import com.v2ray.ang.databinding.ActivitySubEditBinding
|
||||
import com.v2ray.ang.dto.SubscriptionItem
|
||||
import com.v2ray.ang.extension.toast
|
||||
import com.v2ray.ang.extension.toastSuccess
|
||||
import com.v2ray.ang.handler.MmkvManager
|
||||
import com.v2ray.ang.util.Utils
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -18,8 +19,8 @@ import kotlinx.coroutines.launch
|
||||
class SubEditActivity : BaseActivity() {
|
||||
private val binding by lazy { ActivitySubEditBinding.inflate(layoutInflater) }
|
||||
|
||||
var del_config: MenuItem? = null
|
||||
var save_config: MenuItem? = null
|
||||
private var del_config: MenuItem? = null
|
||||
private var save_config: MenuItem? = null
|
||||
|
||||
private val editSubId by lazy { intent.getStringExtra("subId").orEmpty() }
|
||||
|
||||
@@ -37,7 +38,7 @@ class SubEditActivity : BaseActivity() {
|
||||
}
|
||||
|
||||
/**
|
||||
* bingding seleced server config
|
||||
* binding selected server config
|
||||
*/
|
||||
private fun bindingServer(subItem: SubscriptionItem): Boolean {
|
||||
binding.etRemarks.text = Utils.getEditable(subItem.remarks)
|
||||
@@ -94,7 +95,7 @@ class SubEditActivity : BaseActivity() {
|
||||
}
|
||||
|
||||
MmkvManager.encodeSubscription(editSubId, subItem)
|
||||
toast(R.string.toast_success)
|
||||
toastSuccess(R.string.toast_success)
|
||||
finish()
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.v2ray.ang.ui
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
@@ -10,7 +11,8 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.v2ray.ang.R
|
||||
import com.v2ray.ang.databinding.ActivitySubSettingBinding
|
||||
import com.v2ray.ang.dto.SubscriptionItem
|
||||
import com.v2ray.ang.extension.toast
|
||||
import com.v2ray.ang.extension.toastError
|
||||
import com.v2ray.ang.extension.toastSuccess
|
||||
import com.v2ray.ang.handler.AngConfigManager
|
||||
import com.v2ray.ang.handler.MmkvManager
|
||||
import com.v2ray.ang.helper.SimpleItemTouchHelperCallback
|
||||
@@ -64,9 +66,9 @@ class SubSettingActivity : BaseActivity() {
|
||||
delay(500L)
|
||||
launch(Dispatchers.Main) {
|
||||
if (count > 0) {
|
||||
toast(R.string.toast_success)
|
||||
toastSuccess(R.string.toast_success)
|
||||
} else {
|
||||
toast(R.string.toast_failure)
|
||||
toastError(R.string.toast_failure)
|
||||
}
|
||||
binding.pbWaiting.hide()
|
||||
}
|
||||
@@ -79,6 +81,7 @@ class SubSettingActivity : BaseActivity() {
|
||||
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
fun refreshData() {
|
||||
subscriptions = MmkvManager.decodeSubscriptions()
|
||||
adapter.notifyDataSetChanged()
|
||||
|
||||
@@ -28,7 +28,7 @@ class TaskerActivity : BaseActivity() {
|
||||
lstData.add("Default")
|
||||
lstGuid.add(AppConfig.TASKER_DEFAULT_GUID)
|
||||
|
||||
MmkvManager.decodeServerList()?.forEach { key ->
|
||||
MmkvManager.decodeServerList().forEach { key ->
|
||||
MmkvManager.decodeServerConfig(key)?.let { config ->
|
||||
lstData.add(config.remarks)
|
||||
lstGuid.add(key)
|
||||
|
||||
@@ -8,6 +8,7 @@ import androidx.lifecycle.lifecycleScope
|
||||
import com.v2ray.ang.R
|
||||
import com.v2ray.ang.databinding.ActivityLogcatBinding
|
||||
import com.v2ray.ang.extension.toast
|
||||
import com.v2ray.ang.extension.toastError
|
||||
import com.v2ray.ang.handler.AngConfigManager
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -44,7 +45,7 @@ class UrlSchemeActivity : BaseActivity() {
|
||||
}
|
||||
|
||||
else -> {
|
||||
toast(R.string.toast_failure)
|
||||
toastError(R.string.toast_failure)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@ import com.v2ray.ang.databinding.ItemRecyclerUserAssetBinding
|
||||
import com.v2ray.ang.dto.AssetUrlItem
|
||||
import com.v2ray.ang.extension.toTrafficString
|
||||
import com.v2ray.ang.extension.toast
|
||||
import com.v2ray.ang.extension.toastError
|
||||
import com.v2ray.ang.extension.toastSuccess
|
||||
import com.v2ray.ang.handler.MmkvManager
|
||||
import com.v2ray.ang.handler.SettingsManager
|
||||
import com.v2ray.ang.util.HttpUtil
|
||||
@@ -91,7 +93,7 @@ class UserAssetActivity : BaseActivity() {
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
binding.recyclerView.adapter?.notifyDataSetChanged()
|
||||
refreshData()
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
@@ -117,7 +119,7 @@ class UserAssetActivity : BaseActivity() {
|
||||
requestStoragePermissionLauncher.launch(permission)
|
||||
}
|
||||
|
||||
val chooseFile = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
||||
private val chooseFile = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
||||
val uri = result.data?.data
|
||||
if (result.resultCode == RESULT_OK && uri != null) {
|
||||
val assetId = Utils.getUuid()
|
||||
@@ -135,7 +137,7 @@ class UserAssetActivity : BaseActivity() {
|
||||
copyFile(uri)
|
||||
}
|
||||
}.onFailure {
|
||||
toast(R.string.toast_asset_copy_failed)
|
||||
toastError(R.string.toast_asset_copy_failed)
|
||||
MmkvManager.removeAssetUrl(assetId)
|
||||
}
|
||||
}
|
||||
@@ -146,8 +148,8 @@ class UserAssetActivity : BaseActivity() {
|
||||
contentResolver.openInputStream(uri).use { inputStream ->
|
||||
targetFile.outputStream().use { fileOut ->
|
||||
inputStream?.copyTo(fileOut)
|
||||
toast(R.string.toast_success)
|
||||
binding.recyclerView.adapter?.notifyDataSetChanged()
|
||||
toastSuccess(R.string.toast_success)
|
||||
refreshData()
|
||||
}
|
||||
}
|
||||
return targetFile.path
|
||||
@@ -215,7 +217,7 @@ class UserAssetActivity : BaseActivity() {
|
||||
withContext(Dispatchers.Main) {
|
||||
if (resultCount > 0) {
|
||||
toast(getString(R.string.title_update_config_count, resultCount))
|
||||
binding.recyclerView.adapter?.notifyDataSetChanged()
|
||||
refreshData()
|
||||
} else {
|
||||
toast(getString(R.string.toast_failure))
|
||||
}
|
||||
@@ -269,11 +271,16 @@ class UserAssetActivity : BaseActivity() {
|
||||
lifecycleScope.launch(Dispatchers.Default) {
|
||||
SettingsManager.initAssets(this@UserAssetActivity, assets)
|
||||
withContext(Dispatchers.Main) {
|
||||
binding.recyclerView.adapter?.notifyDataSetChanged()
|
||||
refreshData()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
fun refreshData() {
|
||||
binding.recyclerView.adapter?.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
inner class UserAssetAdapter : RecyclerView.Adapter<UserAssetViewHolder>() {
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserAssetViewHolder {
|
||||
return UserAssetViewHolder(
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.v2ray.ang.R
|
||||
import com.v2ray.ang.databinding.ActivityUserAssetUrlBinding
|
||||
import com.v2ray.ang.dto.AssetUrlItem
|
||||
import com.v2ray.ang.extension.toast
|
||||
import com.v2ray.ang.extension.toastSuccess
|
||||
import com.v2ray.ang.handler.MmkvManager
|
||||
import com.v2ray.ang.util.Utils
|
||||
import java.io.File
|
||||
@@ -21,10 +22,10 @@ class UserAssetUrlActivity : BaseActivity() {
|
||||
|
||||
private val binding by lazy { ActivityUserAssetUrlBinding.inflate(layoutInflater) }
|
||||
|
||||
var del_config: MenuItem? = null
|
||||
var save_config: MenuItem? = null
|
||||
private var del_config: MenuItem? = null
|
||||
private var save_config: MenuItem? = null
|
||||
|
||||
val extDir by lazy { File(Utils.userAssetPath(this)) }
|
||||
private val extDir by lazy { File(Utils.userAssetPath(this)) }
|
||||
private val editAssetId by lazy { intent.getStringExtra("assetId").orEmpty() }
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@@ -41,6 +42,7 @@ class UserAssetUrlActivity : BaseActivity() {
|
||||
binding.etRemarks.setText(assetNameQrcode)
|
||||
binding.etUrl.setText(assetUrlQrcode)
|
||||
}
|
||||
|
||||
else -> clearAsset()
|
||||
}
|
||||
}
|
||||
@@ -101,7 +103,7 @@ class UserAssetUrlActivity : BaseActivity() {
|
||||
}
|
||||
|
||||
MmkvManager.encodeAsset(assetId, assetItem)
|
||||
toast(R.string.toast_success)
|
||||
toastSuccess(R.string.toast_success)
|
||||
finish()
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -18,7 +18,8 @@ import com.v2ray.ang.R
|
||||
import com.v2ray.ang.dto.ProfileItem
|
||||
import com.v2ray.ang.dto.ServersCache
|
||||
import com.v2ray.ang.extension.serializable
|
||||
import com.v2ray.ang.extension.toast
|
||||
import com.v2ray.ang.extension.toastError
|
||||
import com.v2ray.ang.extension.toastSuccess
|
||||
import com.v2ray.ang.handler.AngConfigManager
|
||||
import com.v2ray.ang.handler.MmkvManager
|
||||
import com.v2ray.ang.handler.SettingsManager
|
||||
@@ -419,12 +420,12 @@ class MainViewModel(application: Application) : AndroidViewModel(application) {
|
||||
}
|
||||
|
||||
AppConfig.MSG_STATE_START_SUCCESS -> {
|
||||
getApplication<AngApplication>().toast(R.string.toast_services_success)
|
||||
getApplication<AngApplication>().toastSuccess(R.string.toast_services_success)
|
||||
isRunning.value = true
|
||||
}
|
||||
|
||||
AppConfig.MSG_STATE_START_FAILURE -> {
|
||||
getApplication<AngApplication>().toast(R.string.toast_services_failure)
|
||||
getApplication<AngApplication>().toastError(R.string.toast_services_failure)
|
||||
isRunning.value = false
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:pathData="M537,85.3A85.3,85.3 0,0 1,597.3 110.3L828.3,341.3A85.3,85.3 0,0 1,853.3 401.7L853.3,810.7a128,128 0,0 1,-128 128L298.7,938.7a128,128 0,0 1,-128 -128L170.7,213.3a128,128 0,0 1,128 -128zM537,170.7L298.7,170.7a42.7,42.7 0,0 0,-42.7 42.7v597.3a42.7,42.7 0,0 0,42.7 42.7h426.7a42.7,42.7 0,0 0,42.7 -42.7L768,401.7L537,170.7zM512,384a42.7,42.7 0,0 1,42.4 37.7L554.7,426.7v85.3h85.3a42.7,42.7 0,0 1,5 85L640,597.3h-85.3v85.3a42.7,42.7 0,0 1,-85 5L469.3,682.7v-85.3L384,597.3a42.7,42.7 0,0 1,-5 -85L384,512h85.3v-85.3a42.7,42.7 0,0 1,42.7 -42.7z"
|
||||
android:fillColor="#FFFFFFFF" />
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M537,85.3A85.3,85.3 0,0 1,597.3 110.3L828.3,341.3A85.3,85.3 0,0 1,853.3 401.7L853.3,810.7a128,128 0,0 1,-128 128L298.7,938.7a128,128 0,0 1,-128 -128L170.7,213.3a128,128 0,0 1,128 -128zM537,170.7L298.7,170.7a42.7,42.7 0,0 0,-42.7 42.7v597.3a42.7,42.7 0,0 0,42.7 42.7h426.7a42.7,42.7 0,0 0,42.7 -42.7L768,401.7L537,170.7zM512,384a42.7,42.7 0,0 1,42.4 37.7L554.7,426.7v85.3h85.3a42.7,42.7 0,0 1,5 85L640,597.3h-85.3v85.3a42.7,42.7 0,0 1,-85 5L469.3,682.7v-85.3L384,597.3a42.7,42.7 0,0 1,-5 -85L384,512h85.3v-85.3a42.7,42.7 0,0 1,42.7 -42.7z" />
|
||||
</vector>
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:pathData="M273.2,212.8h583.7L856.9,906.2h-583.7L273.2,212.8zM344.9,284.5L344.9,834.6h440.3L785.2,284.5h-440.3z"
|
||||
android:fillColor="#FFFFFFFF" />
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M273.2,212.8h583.7L856.9,906.2h-583.7L273.2,212.8zM344.9,284.5L344.9,834.6h440.3L785.2,284.5h-440.3z" />
|
||||
<path
|
||||
android:pathData="M167.1,117.8h554.4v123.6h-71.7V189.4H238.8v498.8h73.9v71.7H167.1V117.8z"
|
||||
android:fillColor="#FFFFFFFF" />
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M167.1,117.8h554.4v123.6h-71.7V189.4H238.8v498.8h73.9v71.7H167.1V117.8z" />
|
||||
<path
|
||||
android:pathData="M674.8,504H455.3v-71.7h219.4v71.7zM674.8,650.2H455.3v-71.7h219.4v71.7z"
|
||||
android:fillColor="#FFFFFFFF" />
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M674.8,504H455.3v-71.7h219.4v71.7zM674.8,650.2H455.3v-71.7h219.4v71.7z" />
|
||||
</vector>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<vector android:height="24dp"
|
||||
android:tint="#FFFFFF"
|
||||
android:viewportHeight="24"
|
||||
android:viewportWidth="24"
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
android:height="24dp"
|
||||
android:tint="#FFFFFF"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M7,6h10l-5.01,6.3L7,6zM4.25,5.61C6.27,8.2 10,13 10,13v6c0,0.55 0.45,1 1,1h2c0.55,0 1,-0.45 1,-1v-6c0,0 3.72,-4.8 5.74,-7.39C20.25,4.95 19.78,4 18.95,4H5.04C4.21,4 3.74,4.95 4.25,5.61z" />
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:pathData="M723.9,312c-13.2,-13.2 -34.7,-13.2 -47.9,0 -6.6,6.6 -9.9,15.3 -9.9,23.9 0,8.7 3.3,17.3 9.9,23.9 65.9,65.9 80.9,165.5 37.3,247.8 -4.9,9.2 -10.5,18.2 -16.9,26.8 -6.4,8.7 -12.9,16.4 -20,23.3 -13.4,13.1 -13.7,34.5 -0.6,47.9 13.1,13.4 34.5,13.7 47.9,0.6 9.7,-9.5 18.9,-20.2 27.3,-31.6 8.3,-11.2 15.7,-23 22.2,-35.2 57.5,-108.7 37.7,-240.3 -49.3,-327.4zM507.6,470c-0.2,-0.2 -0.4,-0.3 -0.7,-0.5 -0.8,-0.3 -1.7,-0.1 -2.3,0.5 -0.2,0.2 -0.3,0.4 -0.5,0.7 -0.1,0.3 -0.2,0.5 -0.2,0.8 0,0.6 0.3,1.1 0.6,1.5 0.2,0.2 0.4,0.3 0.7,0.5 0.3,0.1 0.5,0.2 0.8,0.2 0.6,0 1.1,-0.3 1.5,-0.6 0.4,-0.4 0.6,-1 0.6,-1.5 0,-0.3 -0.1,-0.5 -0.2,-0.8 0,-0.4 -0.2,-0.6 -0.3,-0.8z"
|
||||
android:fillColor="#FFFFFFFF" />
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M723.9,312c-13.2,-13.2 -34.7,-13.2 -47.9,0 -6.6,6.6 -9.9,15.3 -9.9,23.9 0,8.7 3.3,17.3 9.9,23.9 65.9,65.9 80.9,165.5 37.3,247.8 -4.9,9.2 -10.5,18.2 -16.9,26.8 -6.4,8.7 -12.9,16.4 -20,23.3 -13.4,13.1 -13.7,34.5 -0.6,47.9 13.1,13.4 34.5,13.7 47.9,0.6 9.7,-9.5 18.9,-20.2 27.3,-31.6 8.3,-11.2 15.7,-23 22.2,-35.2 57.5,-108.7 37.7,-240.3 -49.3,-327.4zM507.6,470c-0.2,-0.2 -0.4,-0.3 -0.7,-0.5 -0.8,-0.3 -1.7,-0.1 -2.3,0.5 -0.2,0.2 -0.3,0.4 -0.5,0.7 -0.1,0.3 -0.2,0.5 -0.2,0.8 0,0.6 0.3,1.1 0.6,1.5 0.2,0.2 0.4,0.3 0.7,0.5 0.3,0.1 0.5,0.2 0.8,0.2 0.6,0 1.1,-0.3 1.5,-0.6 0.4,-0.4 0.6,-1 0.6,-1.5 0,-0.3 -0.1,-0.5 -0.2,-0.8 0,-0.4 -0.2,-0.6 -0.3,-0.8z" />
|
||||
<path
|
||||
android:pathData="M833.7,209.6c-13.2,-13.2 -34.5,-13.2 -47.6,0 -13.2,13.2 -13.2,34.5 0,47.6 122.3,122.3 140,314.4 42.1,456.6 -12.5,18.1 -26.5,35 -42.1,50.5 -6.6,6.6 -9.9,15.2 -9.9,23.8 0,8.6 3.3,17.2 9.9,23.8 13.2,13.2 34.5,13.2 47.6,0 18.4,-18.4 35.1,-38.5 49.9,-60C1000,583.1 979,355 833.7,209.6zM515.1,166.8c-48,-22.3 -102.9,-15.1 -143.4,19L176.6,349.9h-50.2c-31,0 -63.3,25.2 -63.3,56.3v209.4c0,31 32.2,56.3 63.3,56.3h50.2L371.7,836c24.9,21 55.4,31.8 86.2,31.8 19.3,0 38.7,-4.2 57.2,-12.8 48,-22.3 77.8,-69.1 77.8,-122L592.9,288.8c0,-52.9 -29.8,-99.6 -77.8,-122zM531.1,732.9c0,31.8 -17.2,52.9 -46.1,66.3 -28.9,13.4 -56.7,6.2 -81,-14.3L206.2,623.5c-4.9,-4.2 -11.2,-6.4 -17.6,-6.4h-60.2c-0.8,0 -1.5,-0.7 -1.5,-1.5L126.9,406.2c0,-0.8 0.7,-1.5 1.5,-1.5h60.2c6.5,0 12.7,-2.3 17.6,-6.4L412,237.7c24.4,-20.5 51.2,-24.7 80,-11.3 28.9,13.4 39.1,30.5 39.1,62.3v444.2z"
|
||||
android:fillColor="#FFFFFFFF" />
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M833.7,209.6c-13.2,-13.2 -34.5,-13.2 -47.6,0 -13.2,13.2 -13.2,34.5 0,47.6 122.3,122.3 140,314.4 42.1,456.6 -12.5,18.1 -26.5,35 -42.1,50.5 -6.6,6.6 -9.9,15.2 -9.9,23.8 0,8.6 3.3,17.2 9.9,23.8 13.2,13.2 34.5,13.2 47.6,0 18.4,-18.4 35.1,-38.5 49.9,-60C1000,583.1 979,355 833.7,209.6zM515.1,166.8c-48,-22.3 -102.9,-15.1 -143.4,19L176.6,349.9h-50.2c-31,0 -63.3,25.2 -63.3,56.3v209.4c0,31 32.2,56.3 63.3,56.3h50.2L371.7,836c24.9,21 55.4,31.8 86.2,31.8 19.3,0 38.7,-4.2 57.2,-12.8 48,-22.3 77.8,-69.1 77.8,-122L592.9,288.8c0,-52.9 -29.8,-99.6 -77.8,-122zM531.1,732.9c0,31.8 -17.2,52.9 -46.1,66.3 -28.9,13.4 -56.7,6.2 -81,-14.3L206.2,623.5c-4.9,-4.2 -11.2,-6.4 -17.6,-6.4h-60.2c-0.8,0 -1.5,-0.7 -1.5,-1.5L126.9,406.2c0,-0.8 0.7,-1.5 1.5,-1.5h60.2c6.5,0 12.7,-2.3 17.6,-6.4L412,237.7c24.4,-20.5 51.2,-24.7 80,-11.3 28.9,13.4 39.1,30.5 39.1,62.3v444.2z" />
|
||||
</vector>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportHeight="24.0"
|
||||
android:viewportWidth="24.0"
|
||||
android:width="24dp">
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M3,5h2L5,3c-1.1,0 -2,0.9 -2,2zM3,13h2v-2L3,11v2zM7,21h2v-2L7,19v2zM3,9h2L5,7L3,7v2zM13,3h-2v2h2L13,3zM19,3v2h2c0,-1.1 -0.9,-2 -2,-2zM5,21v-2L3,19c0,1.1 0.9,2 2,2zM3,17h2v-2L3,15v2zM9,3L7,3v2h2L9,3zM11,21h2v-2h-2v2zM19,13h2v-2h-2v2zM19,21c1.1,0 2,-0.9 2,-2h-2v2zM19,9h2L21,7h-2v2zM19,17h2v-2h-2v2zM15,21h2v-2h-2v2zM15,5h2L17,3h-2v2zM7,17h10L17,7L7,7v10zM9,9h6v6L9,15L9,9z" />
|
||||
|
||||
@@ -3,5 +3,5 @@
|
||||
<solid android:color="@color/divider_color_light" />
|
||||
<size
|
||||
android:width="48dp"
|
||||
android:height="48dp"/>
|
||||
android:height="48dp" />
|
||||
</shape>
|
||||
@@ -4,6 +4,6 @@
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:pathData="M537,85.3A85.3,85.3 0,0 1,597.3 110.3L828.3,341.3A85.3,85.3 0,0 1,853.3 401.7L853.3,810.7a128,128 0,0 1,-128 128L298.7,938.7a128,128 0,0 1,-128 -128L170.7,213.3a128,128 0,0 1,128 -128zM537,170.7L298.7,170.7a42.7,42.7 0,0 0,-42.7 42.7v597.3a42.7,42.7 0,0 0,42.7 42.7h426.7a42.7,42.7 0,0 0,42.7 -42.7L768,401.7L537,170.7zM512,384a42.7,42.7 0,0 1,42.4 37.7L554.7,426.7v85.3h85.3a42.7,42.7 0,0 1,5 85L640,597.3h-85.3v85.3a42.7,42.7 0,0 1,-85 5L469.3,682.7v-85.3L384,597.3a42.7,42.7 0,0 1,-5 -85L384,512h85.3v-85.3a42.7,42.7 0,0 1,42.7 -42.7z"
|
||||
android:fillColor="#FF000000" />
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M537,85.3A85.3,85.3 0,0 1,597.3 110.3L828.3,341.3A85.3,85.3 0,0 1,853.3 401.7L853.3,810.7a128,128 0,0 1,-128 128L298.7,938.7a128,128 0,0 1,-128 -128L170.7,213.3a128,128 0,0 1,128 -128zM537,170.7L298.7,170.7a42.7,42.7 0,0 0,-42.7 42.7v597.3a42.7,42.7 0,0 0,42.7 42.7h426.7a42.7,42.7 0,0 0,42.7 -42.7L768,401.7L537,170.7zM512,384a42.7,42.7 0,0 1,42.4 37.7L554.7,426.7v85.3h85.3a42.7,42.7 0,0 1,5 85L640,597.3h-85.3v85.3a42.7,42.7 0,0 1,-85 5L469.3,682.7v-85.3L384,597.3a42.7,42.7 0,0 1,-5 -85L384,512h85.3v-85.3a42.7,42.7 0,0 1,42.7 -42.7z" />
|
||||
</vector>
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:pathData="M273.2,212.8h583.7L856.9,906.2h-583.7L273.2,212.8zM344.9,284.5L344.9,834.6h440.3L785.2,284.5h-440.3z"
|
||||
android:fillColor="#FF000000" />
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M273.2,212.8h583.7L856.9,906.2h-583.7L273.2,212.8zM344.9,284.5L344.9,834.6h440.3L785.2,284.5h-440.3z" />
|
||||
<path
|
||||
android:pathData="M167.1,117.8h554.4v123.6h-71.7V189.4H238.8v498.8h73.9v71.7H167.1V117.8z"
|
||||
android:fillColor="#FF000000" />
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M167.1,117.8h554.4v123.6h-71.7V189.4H238.8v498.8h73.9v71.7H167.1V117.8z" />
|
||||
<path
|
||||
android:pathData="M674.8,504H455.3v-71.7h219.4v71.7zM674.8,650.2H455.3v-71.7h219.4v71.7z"
|
||||
android:fillColor="#FF000000" />
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M674.8,504H455.3v-71.7h219.4v71.7zM674.8,650.2H455.3v-71.7h219.4v71.7z" />
|
||||
</vector>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<vector android:height="24dp"
|
||||
android:tint="#000000"
|
||||
android:viewportHeight="24"
|
||||
android:viewportWidth="24"
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
android:height="24dp"
|
||||
android:tint="#000000"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M7,6h10l-5.01,6.3L7,6zM4.25,5.61C6.27,8.2 10,13 10,13v6c0,0.55 0.45,1 1,1h2c0.55,0 1,-0.45 1,-1v-6c0,0 3.72,-4.8 5.74,-7.39C20.25,4.95 19.78,4 18.95,4H5.04C4.21,4 3.74,4.95 4.25,5.61z" />
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:pathData="M723.9,312c-13.2,-13.2 -34.7,-13.2 -47.9,0 -6.6,6.6 -9.9,15.3 -9.9,23.9 0,8.7 3.3,17.3 9.9,23.9 65.9,65.9 80.9,165.5 37.3,247.8 -4.9,9.2 -10.5,18.2 -16.9,26.8 -6.4,8.7 -12.9,16.4 -20,23.3 -13.4,13.1 -13.7,34.5 -0.6,47.9 13.1,13.4 34.5,13.7 47.9,0.6 9.7,-9.5 18.9,-20.2 27.3,-31.6 8.3,-11.2 15.7,-23 22.2,-35.2 57.5,-108.7 37.7,-240.3 -49.3,-327.4zM507.6,470c-0.2,-0.2 -0.4,-0.3 -0.7,-0.5 -0.8,-0.3 -1.7,-0.1 -2.3,0.5 -0.2,0.2 -0.3,0.4 -0.5,0.7 -0.1,0.3 -0.2,0.5 -0.2,0.8 0,0.6 0.3,1.1 0.6,1.5 0.2,0.2 0.4,0.3 0.7,0.5 0.3,0.1 0.5,0.2 0.8,0.2 0.6,0 1.1,-0.3 1.5,-0.6 0.4,-0.4 0.6,-1 0.6,-1.5 0,-0.3 -0.1,-0.5 -0.2,-0.8 0,-0.4 -0.2,-0.6 -0.3,-0.8z"
|
||||
android:fillColor="#FF000000" />
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M723.9,312c-13.2,-13.2 -34.7,-13.2 -47.9,0 -6.6,6.6 -9.9,15.3 -9.9,23.9 0,8.7 3.3,17.3 9.9,23.9 65.9,65.9 80.9,165.5 37.3,247.8 -4.9,9.2 -10.5,18.2 -16.9,26.8 -6.4,8.7 -12.9,16.4 -20,23.3 -13.4,13.1 -13.7,34.5 -0.6,47.9 13.1,13.4 34.5,13.7 47.9,0.6 9.7,-9.5 18.9,-20.2 27.3,-31.6 8.3,-11.2 15.7,-23 22.2,-35.2 57.5,-108.7 37.7,-240.3 -49.3,-327.4zM507.6,470c-0.2,-0.2 -0.4,-0.3 -0.7,-0.5 -0.8,-0.3 -1.7,-0.1 -2.3,0.5 -0.2,0.2 -0.3,0.4 -0.5,0.7 -0.1,0.3 -0.2,0.5 -0.2,0.8 0,0.6 0.3,1.1 0.6,1.5 0.2,0.2 0.4,0.3 0.7,0.5 0.3,0.1 0.5,0.2 0.8,0.2 0.6,0 1.1,-0.3 1.5,-0.6 0.4,-0.4 0.6,-1 0.6,-1.5 0,-0.3 -0.1,-0.5 -0.2,-0.8 0,-0.4 -0.2,-0.6 -0.3,-0.8z" />
|
||||
<path
|
||||
android:pathData="M833.7,209.6c-13.2,-13.2 -34.5,-13.2 -47.6,0 -13.2,13.2 -13.2,34.5 0,47.6 122.3,122.3 140,314.4 42.1,456.6 -12.5,18.1 -26.5,35 -42.1,50.5 -6.6,6.6 -9.9,15.2 -9.9,23.8 0,8.6 3.3,17.2 9.9,23.8 13.2,13.2 34.5,13.2 47.6,0 18.4,-18.4 35.1,-38.5 49.9,-60C1000,583.1 979,355 833.7,209.6zM515.1,166.8c-48,-22.3 -102.9,-15.1 -143.4,19L176.6,349.9h-50.2c-31,0 -63.3,25.2 -63.3,56.3v209.4c0,31 32.2,56.3 63.3,56.3h50.2L371.7,836c24.9,21 55.4,31.8 86.2,31.8 19.3,0 38.7,-4.2 57.2,-12.8 48,-22.3 77.8,-69.1 77.8,-122L592.9,288.8c0,-52.9 -29.8,-99.6 -77.8,-122zM531.1,732.9c0,31.8 -17.2,52.9 -46.1,66.3 -28.9,13.4 -56.7,6.2 -81,-14.3L206.2,623.5c-4.9,-4.2 -11.2,-6.4 -17.6,-6.4h-60.2c-0.8,0 -1.5,-0.7 -1.5,-1.5L126.9,406.2c0,-0.8 0.7,-1.5 1.5,-1.5h60.2c6.5,0 12.7,-2.3 17.6,-6.4L412,237.7c24.4,-20.5 51.2,-24.7 80,-11.3 28.9,13.4 39.1,30.5 39.1,62.3v444.2z"
|
||||
android:fillColor="#FF000000" />
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M833.7,209.6c-13.2,-13.2 -34.5,-13.2 -47.6,0 -13.2,13.2 -13.2,34.5 0,47.6 122.3,122.3 140,314.4 42.1,456.6 -12.5,18.1 -26.5,35 -42.1,50.5 -6.6,6.6 -9.9,15.2 -9.9,23.8 0,8.6 3.3,17.2 9.9,23.8 13.2,13.2 34.5,13.2 47.6,0 18.4,-18.4 35.1,-38.5 49.9,-60C1000,583.1 979,355 833.7,209.6zM515.1,166.8c-48,-22.3 -102.9,-15.1 -143.4,19L176.6,349.9h-50.2c-31,0 -63.3,25.2 -63.3,56.3v209.4c0,31 32.2,56.3 63.3,56.3h50.2L371.7,836c24.9,21 55.4,31.8 86.2,31.8 19.3,0 38.7,-4.2 57.2,-12.8 48,-22.3 77.8,-69.1 77.8,-122L592.9,288.8c0,-52.9 -29.8,-99.6 -77.8,-122zM531.1,732.9c0,31.8 -17.2,52.9 -46.1,66.3 -28.9,13.4 -56.7,6.2 -81,-14.3L206.2,623.5c-4.9,-4.2 -11.2,-6.4 -17.6,-6.4h-60.2c-0.8,0 -1.5,-0.7 -1.5,-1.5L126.9,406.2c0,-0.8 0.7,-1.5 1.5,-1.5h60.2c6.5,0 12.7,-2.3 17.6,-6.4L412,237.7c24.4,-20.5 51.2,-24.7 80,-11.3 28.9,13.4 39.1,30.5 39.1,62.3v444.2z" />
|
||||
</vector>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportHeight="1024"
|
||||
android:viewportWidth="1024">
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M0,512C0,229.23 229.81,0 512,0 794.77,0 1024,229.81 1024,512 1024,794.77 794.19,1024 512,1024 229.23,1024 0,794.19 0,512Z" />
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<vector android:height="24dp"
|
||||
android:viewportHeight="1024"
|
||||
android:viewportWidth="1024"
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
android:height="24dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M469.2,802.1l-81.7,-24.6L554.8,221.9l81.7,24.6L469.2,802.1zM362.7,654.5l-124.7,-141.7 124.8,-143.5 -64.4,-56 -173.8,199.8 174,197.7 64.1,-56.3zM899.4,513.1l-173.8,-199.8 -64.4,56 124.8,143.5 -124.7,141.7 64.1,56.4 174,-197.7z" />
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M480,520Q430,520 395,485Q360,450 360,400Q360,350 395,315Q430,280 480,280Q530,280 565,315Q600,350 600,400Q600,450 565,485Q530,520 480,520ZM240,920L240,611Q202,569 181,515Q160,461 160,400Q160,266 253,173Q346,80 480,80Q614,80 707,173Q800,266 800,400Q800,461 779,515Q758,569 720,611L720,920L480,840L240,920ZM480,640Q580,640 650,570Q720,500 720,400Q720,300 650,230Q580,160 480,160Q380,160 310,230Q240,300 240,400Q240,500 310,570Q380,640 480,640ZM320,801L480,760L640,801L640,677Q605,697 564.5,708.5Q524,720 480,720Q436,720 395.5,708.5Q355,697 320,677L320,801ZM480,739L480,739Q480,739 480,739Q480,739 480,739Q480,739 480,739Q480,739 480,739L480,739L480,739Z"/>
|
||||
android:viewportHeight="960">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M480,520Q430,520 395,485Q360,450 360,400Q360,350 395,315Q430,280 480,280Q530,280 565,315Q600,350 600,400Q600,450 565,485Q530,520 480,520ZM240,920L240,611Q202,569 181,515Q160,461 160,400Q160,266 253,173Q346,80 480,80Q614,80 707,173Q800,266 800,400Q800,461 779,515Q758,569 720,611L720,920L480,840L240,920ZM480,640Q580,640 650,570Q720,500 720,400Q720,300 650,230Q580,160 480,160Q380,160 310,230Q240,300 240,400Q240,500 310,570Q380,640 480,640ZM320,801L480,760L640,801L640,677Q605,697 564.5,708.5Q524,720 480,720Q436,720 395.5,708.5Q355,697 320,677L320,801ZM480,739L480,739Q480,739 480,739Q480,739 480,739Q480,739 480,739Q480,739 480,739L480,739L480,739Z" />
|
||||
</vector>
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_view"
|
||||
android:scrollbars="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scrollbars="vertical"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
|
||||
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
|
||||
@@ -55,11 +55,11 @@
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_view"
|
||||
android:scrollbars="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:nextFocusRight="@+id/fab" />
|
||||
android:nextFocusRight="@+id/fab"
|
||||
android:scrollbars="vertical" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_test"
|
||||
@@ -68,8 +68,8 @@
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:nextFocusLeft="@+id/recycler_view"
|
||||
android:orientation="vertical"
|
||||
android:nextFocusRight="@+id/fab">
|
||||
android:nextFocusRight="@+id/fab"
|
||||
android:orientation="vertical">
|
||||
|
||||
<View
|
||||
android:layout_width="wrap_content"
|
||||
@@ -80,9 +80,9 @@
|
||||
android:id="@+id/tv_test_state"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="start|center"
|
||||
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" />
|
||||
@@ -94,19 +94,18 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_marginEnd="@dimen/padding_spacing_dp16"
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp8">
|
||||
android:layout_marginEnd="@dimen/padding_spacing_dp16">
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/fab"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_marginBottom="@dimen/view_height_dp64"
|
||||
android:layout_marginBottom="@dimen/view_height_dp36"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:nextFocusLeft="@+id/layout_test"
|
||||
android:src="@drawable/ic_stat_name"
|
||||
android:src="@drawable/ic_play_24dp"
|
||||
app:layout_anchorGravity="bottom|right|end" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
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">
|
||||
|
||||
@@ -172,11 +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="wrap_content"
|
||||
android:layout_marginTop="@dimen/padding_spacing_dp8"
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp8"
|
||||
android:entries="@array/outbound_tag" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -29,13 +29,13 @@
|
||||
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"
|
||||
android:paddingTop="@dimen/padding_spacing_dp8"
|
||||
android:entries="@array/routing_domain_strategy" />
|
||||
android:layout_marginTop="@dimen/padding_spacing_dp8"
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp8"
|
||||
android:entries="@array/routing_domain_strategy"
|
||||
android:paddingTop="@dimen/padding_spacing_dp8" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
|
||||
@@ -46,11 +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="wrap_content"
|
||||
android:layout_marginTop="@dimen/padding_spacing_dp8"
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp8"
|
||||
android:entries="@array/ss_securitys" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -45,11 +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="wrap_content"
|
||||
android:layout_marginTop="@dimen/padding_spacing_dp8"
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp8"
|
||||
android:entries="@array/flows" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -45,11 +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="wrap_content"
|
||||
android:layout_marginTop="@dimen/padding_spacing_dp8"
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp8"
|
||||
android:entries="@array/securitys" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
android:inputType="text" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
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">
|
||||
|
||||
|
||||
@@ -16,11 +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="wrap_content" />
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/padding_spacing_dp8"
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp8" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:padding="@dimen/padding_spacing_dp8"
|
||||
android:gravity="center_vertical">
|
||||
android:gravity="center_vertical"
|
||||
android:padding="@dimen/padding_spacing_dp8">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/icon"
|
||||
@@ -25,8 +25,8 @@
|
||||
android:id="@+id/name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Subhead"
|
||||
android:maxLines="1" />
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Subhead" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/package_name"
|
||||
@@ -43,6 +43,6 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:clickable="false"
|
||||
android:focusable="false"
|
||||
android:padding="@dimen/padding_spacing_dp8" />
|
||||
android:padding="@dimen/padding_spacing_dp8" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -11,9 +11,9 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:visibility="invisible"
|
||||
android:orientation="horizontal"
|
||||
android:padding="@dimen/padding_spacing_dp16">
|
||||
android:padding="@dimen/padding_spacing_dp16"
|
||||
android:visibility="invisible">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="@dimen/padding_spacing_dp8"
|
||||
android:orientation="vertical">
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/padding_spacing_dp8">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/log_tag"
|
||||
@@ -23,8 +23,8 @@
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/log_content"
|
||||
android:layout_width="match_parent"
|
||||
android:paddingTop="@dimen/padding_spacing_dp8"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="@dimen/padding_spacing_dp8"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
android:gravity="center"
|
||||
android:nextFocusRight="@+id/layout_share"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="@dimen/padding_spacing_dp4"
|
||||
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
|
||||
|
||||
@@ -19,11 +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="wrap_content"
|
||||
android:layout_marginTop="@dimen/padding_spacing_dp8"
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp8"
|
||||
android:entries="@array/streamsecurityxs"
|
||||
android:nextFocusDown="@+id/et_sni" />
|
||||
|
||||
@@ -54,8 +54,8 @@
|
||||
android:id="@+id/lay_stream_fingerprint"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp16">
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp16"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
@@ -63,11 +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="wrap_content"
|
||||
android:layout_marginTop="@dimen/padding_spacing_dp8"
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp8"
|
||||
android:entries="@array/streamsecurity_utls"
|
||||
android:nextFocusDown="@+id/sp_stream_alpn" />
|
||||
|
||||
@@ -77,8 +77,8 @@
|
||||
android:id="@+id/lay_stream_alpn"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp16">
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp16"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
@@ -86,11 +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="wrap_content"
|
||||
android:layout_marginTop="@dimen/padding_spacing_dp8"
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp8"
|
||||
android:entries="@array/streamsecurity_alpn"
|
||||
android:nextFocusDown="@+id/sp_allow_insecure" />
|
||||
|
||||
@@ -108,11 +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="wrap_content"
|
||||
android:layout_marginTop="@dimen/padding_spacing_dp8"
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp8"
|
||||
android:entries="@array/allowinsecures" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -19,11 +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="wrap_content"
|
||||
android:layout_marginTop="@dimen/padding_spacing_dp8"
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp8"
|
||||
android:entries="@array/streamsecuritys"
|
||||
android:nextFocusDown="@+id/et_sni" />
|
||||
|
||||
@@ -63,11 +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="wrap_content"
|
||||
android:layout_marginTop="@dimen/padding_spacing_dp8"
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp8"
|
||||
android:entries="@array/allowinsecures" />
|
||||
|
||||
|
||||
|
||||
@@ -29,11 +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="wrap_content"
|
||||
android:layout_marginTop="@dimen/padding_spacing_dp8"
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp8"
|
||||
android:entries="@array/networks" />
|
||||
</LinearLayout>
|
||||
|
||||
@@ -50,11 +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="wrap_content" />
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/padding_spacing_dp8"
|
||||
android:layout_marginBottom="@dimen/padding_spacing_dp8" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
|
||||
@@ -26,6 +26,6 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="@android:color/white"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small" />
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
android:textColor="@android:color/white" />
|
||||
</LinearLayout>
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
android:id="@+id/routing_setting"
|
||||
android:icon="@drawable/ic_routing_24dp"
|
||||
android:title="@string/routing_settings_title" />
|
||||
<item
|
||||
android:id="@+id/user_asset_setting"
|
||||
android:icon="@drawable/ic_file_24dp"
|
||||
android:title="@string/title_user_asset_setting" />
|
||||
<item
|
||||
android:id="@+id/settings"
|
||||
android:icon="@drawable/ic_settings_24dp"
|
||||
|
||||
@@ -57,28 +57,28 @@
|
||||
android:title="@string/menu_item_import_config_manually_hysteria2"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<!-- <item-->
|
||||
<!-- android:title="@string/menu_item_import_config_custom"-->
|
||||
<!-- app:showAsAction="ifRoom">-->
|
||||
<!-- <menu>-->
|
||||
<!-- <item-->
|
||||
<!-- android:id="@+id/import_config_custom_clipboard"-->
|
||||
<!-- android:title="@string/menu_item_import_config_custom_clipboard"-->
|
||||
<!-- app:showAsAction="never" />-->
|
||||
<!-- <item-->
|
||||
<!-- android:id="@+id/import_config_custom_local"-->
|
||||
<!-- android:title="@string/menu_item_import_config_custom_local"-->
|
||||
<!-- app:showAsAction="never" />-->
|
||||
<!-- <item-->
|
||||
<!-- android:id="@+id/import_config_custom_url"-->
|
||||
<!-- android:title="@string/menu_item_import_config_custom_url"-->
|
||||
<!-- app:showAsAction="never" />-->
|
||||
<!-- <item-->
|
||||
<!-- android:id="@+id/import_config_custom_url_scan"-->
|
||||
<!-- android:title="@string/menu_item_import_config_custom_url_scan"-->
|
||||
<!-- app:showAsAction="never" />-->
|
||||
<!-- </menu>-->
|
||||
<!-- </item>-->
|
||||
<!-- <item-->
|
||||
<!-- android:title="@string/menu_item_import_config_custom"-->
|
||||
<!-- app:showAsAction="ifRoom">-->
|
||||
<!-- <menu>-->
|
||||
<!-- <item-->
|
||||
<!-- android:id="@+id/import_config_custom_clipboard"-->
|
||||
<!-- android:title="@string/menu_item_import_config_custom_clipboard"-->
|
||||
<!-- app:showAsAction="never" />-->
|
||||
<!-- <item-->
|
||||
<!-- android:id="@+id/import_config_custom_local"-->
|
||||
<!-- android:title="@string/menu_item_import_config_custom_local"-->
|
||||
<!-- app:showAsAction="never" />-->
|
||||
<!-- <item-->
|
||||
<!-- android:id="@+id/import_config_custom_url"-->
|
||||
<!-- android:title="@string/menu_item_import_config_custom_url"-->
|
||||
<!-- app:showAsAction="never" />-->
|
||||
<!-- <item-->
|
||||
<!-- android:id="@+id/import_config_custom_url_scan"-->
|
||||
<!-- android:title="@string/menu_item_import_config_custom_url_scan"-->
|
||||
<!-- app:showAsAction="never" />-->
|
||||
<!-- </menu>-->
|
||||
<!-- </item>-->
|
||||
</menu>
|
||||
</item>
|
||||
<item
|
||||
|
||||
@@ -6,10 +6,6 @@
|
||||
android:icon="@drawable/ic_add_24dp"
|
||||
android:title="@string/routing_settings_add_rule"
|
||||
app:showAsAction="ifRoom" />
|
||||
<item
|
||||
android:id="@+id/user_asset_setting"
|
||||
android:icon="@drawable/ic_file_24dp"
|
||||
android:title="@string/title_user_asset_setting" />
|
||||
<item
|
||||
android:id="@+id/import_predefined_rulesets"
|
||||
android:title="@string/routing_settings_import_predefined_rulesets"
|
||||
|
||||
@@ -268,7 +268,7 @@
|
||||
<string name="title_sub_update">تحديث الاشتراك (أول خطوة)</string>
|
||||
<string name="title_ping_all_server">Tcping لجميع الإعدادات</string>
|
||||
<string name="title_real_ping_all_server"> اختبر جميع الإعدادات (3)</string>
|
||||
<string name="title_user_asset_setting">ملفات أصول جغرافية</string>
|
||||
<string name="title_user_asset_setting">Asset files</string>
|
||||
<string name="title_sort_by_test_results">الفرز حسب نتائج الاختبار (5)</string>
|
||||
<string name="title_filter_config">تصفية ملف التكوين</string>
|
||||
<string name="filter_config_all">جميع مجموعات الاشتراك</string>
|
||||
|
||||
@@ -268,7 +268,7 @@
|
||||
<string name="title_sub_update">সাবস্ক্রিপশন আপডেট</string>
|
||||
<string name="title_ping_all_server">সব কনফিগারেশন TCPing</string>
|
||||
<string name="title_real_ping_all_server">সব কনফিগারেশন প্রকৃত বিলম্ব</string>
|
||||
<string name="title_user_asset_setting">জিও অ্যাসেট ফাইলগুলি</string>
|
||||
<string name="title_user_asset_setting">Asset files</string>
|
||||
<string name="title_sort_by_test_results">টেস্ট ফলাফল দ্বারা সাজানো</string>
|
||||
<string name="title_filter_config">কনফিগারেশন ফাইল ফিল্টার করুন</string>
|
||||
<string name="filter_config_all">সব সাবস্ক্রিপশন গ্রুপ</string>
|
||||
|
||||
@@ -268,7 +268,7 @@
|
||||
<string name="title_sub_update">ورۊ کردن اشتراک جرگه سکویی</string>
|
||||
<string name="title_ping_all_server">Tcping کانفیگا جرگه سکویی</string>
|
||||
<string name="title_real_ping_all_server">تئخیر واقعی کانفیگا جرگه سکویی</string>
|
||||
<string name="title_user_asset_setting">فایلا دارایی جوقرافیایی</string>
|
||||
<string name="title_user_asset_setting">Asset files</string>
|
||||
<string name="title_sort_by_test_results">ترتیب و ری نتیجیل آزمایش</string>
|
||||
<string name="title_filter_config">فیلتر کردن کانفیگا</string>
|
||||
<string name="filter_config_all">پوی جرگیل</string>
|
||||
|
||||
@@ -214,8 +214,8 @@
|
||||
<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>
|
||||
<string name="title_pref_double_column_display">فعال کردن نمایش دو ستون</string>
|
||||
<string name="summary_pref_double_column_display">لیست نمایه در دو ستون نمایش داده می شود و امکان نمایش محتوای بیشتری را بر روی صفحه نمایش می دهد. برای اجرا باید برنامه را مجددا راه اندازی کنید.</string>
|
||||
|
||||
<!-- AboutActivity -->
|
||||
<string name="title_pref_feedback">بازخورد</string>
|
||||
@@ -242,7 +242,7 @@
|
||||
<string name="title_mode">حالت</string>
|
||||
<string name="title_mode_help">برای اطلاعات و راهنمایی بیشتر، روی این متن کلیک کنید</string>
|
||||
<string name="title_language">زبان</string>
|
||||
<string name="title_ui_settings">تنظیمات رابط کاربری</string>
|
||||
<string name="title_ui_settings">تنظیمات رابط کاربری</string>
|
||||
<string name="title_pref_ui_mode_night">تنظیمات حالت رابط کاربری</string>
|
||||
|
||||
<string name="title_logcat">گزارشات</string>
|
||||
@@ -265,7 +265,7 @@
|
||||
<string name="title_sub_update">بهروزرسانی گروه فعلی اشتراک</string>
|
||||
<string name="title_ping_all_server">TCPING کانفیگ های گروه فعلی</string>
|
||||
<string name="title_real_ping_all_server">تاخیر واقعی کانفیگ های گروه فعلی</string>
|
||||
<string name="title_user_asset_setting">فایل های دارایی جغرافیا</string>
|
||||
<string name="title_user_asset_setting">Asset files</string>
|
||||
<string name="title_sort_by_test_results">مرتب سازی بر اساس نتایج آزمایش</string>
|
||||
<string name="title_filter_config">فیلتر کردن کانفیگها</string>
|
||||
<string name="filter_config_all">همه گروههای اشتراک</string>
|
||||
@@ -327,10 +327,10 @@
|
||||
|
||||
<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>
|
||||
<item>صادر کردن به کلیپ بورد</item>
|
||||
<item>صادر کردن پیکربندی کامل به کلیپ بورد</item>
|
||||
<item>ویرایش کردن</item>
|
||||
<item>حذف کردن</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="share_sub_method">
|
||||
|
||||
@@ -215,8 +215,8 @@
|
||||
<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>
|
||||
<string name="title_pref_double_column_display">Отображение в два столбца</string>
|
||||
<string name="summary_pref_double_column_display">Список профилей выводится в виде двух столбцов, что позволяет показать больше информации на экране. Требуется перезапуск приложения.</string>
|
||||
|
||||
<!-- AboutActivity -->
|
||||
<string name="title_pref_feedback">Обратная связь</string>
|
||||
@@ -267,7 +267,7 @@
|
||||
<string name="title_sub_update">Обновить подписку группы</string>
|
||||
<string name="title_ping_all_server">Проверка профилей группы</string>
|
||||
<string name="title_real_ping_all_server">Время отклика профилей группы</string>
|
||||
<string name="title_user_asset_setting">Файлы георесурсов</string>
|
||||
<string name="title_user_asset_setting">Asset files</string>
|
||||
<string name="title_sort_by_test_results">Сортировка по результатам теста</string>
|
||||
<string name="title_filter_config">Фильтр групп</string>
|
||||
<string name="filter_config_all">Все группы</string>
|
||||
@@ -328,11 +328,11 @@
|
||||
</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>
|
||||
<item>QR-код</item>
|
||||
<item>Экспорт в буфер обмена</item>
|
||||
<item>Экспорт всей конфигурации в буфер обмена</item>
|
||||
<item>Изменить</item>
|
||||
<item>Удалить</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="share_sub_method">
|
||||
|
||||
@@ -268,7 +268,7 @@
|
||||
<string name="title_sub_update">Cập nhật các gói đăng ký</string>
|
||||
<string name="title_ping_all_server">Ping tất cả máy chủ</string>
|
||||
<string name="title_real_ping_all_server">Kiểm tra HTTP tất cả máy chủ</string>
|
||||
<string name="title_user_asset_setting">Tệp Geo Asset</string>
|
||||
<string name="title_user_asset_setting">Asset files</string>
|
||||
<string name="title_sort_by_test_results">Sắp xếp lại theo lần kiểm tra cuối cùng</string>
|
||||
<string name="title_filter_config">Lọc cấu hình theo các gói đăng ký</string>
|
||||
<string name="filter_config_all">Hiển thị tất cả các gói đăng ký</string>
|
||||
|
||||
@@ -265,7 +265,7 @@
|
||||
<string name="title_sub_update">更新当前组订阅</string>
|
||||
<string name="title_ping_all_server">测试当前组配置 Tcping</string>
|
||||
<string name="title_real_ping_all_server">测试当前组配置真连接</string>
|
||||
<string name="title_user_asset_setting">Geo 资源文件</string>
|
||||
<string name="title_user_asset_setting">资源文件</string>
|
||||
<string name="title_sort_by_test_results">按测试结果排序</string>
|
||||
<string name="title_filter_config">过滤配置文件</string>
|
||||
<string name="filter_config_all">所有分组</string>
|
||||
|
||||
@@ -266,7 +266,7 @@
|
||||
<string name="title_sub_update">更新目前群組訂閱</string>
|
||||
<string name="title_ping_all_server">偵測目前群組設定 Tcping</string>
|
||||
<string name="title_real_ping_all_server">偵測目前群組設定真延遲</string>
|
||||
<string name="title_user_asset_setting">Geo 資源檔案</string>
|
||||
<string name="title_user_asset_setting">資源檔案</string>
|
||||
<string name="title_sort_by_test_results">依偵測結果排序</string>
|
||||
<string name="title_filter_config">過濾設定</string>
|
||||
<string name="filter_config_all">所有分組</string>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<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_dp36">36dp</dimen>
|
||||
<dimen name="view_height_dp48">48dp</dimen>
|
||||
<dimen name="view_height_dp64">64dp</dimen>
|
||||
<dimen name="view_height_dp160">160dp</dimen>
|
||||
|
||||
@@ -269,7 +269,7 @@
|
||||
<string name="title_sub_update">Update current group subscription</string>
|
||||
<string name="title_ping_all_server">Tcping current group configuration</string>
|
||||
<string name="title_real_ping_all_server">Real delay current group configuration</string>
|
||||
<string name="title_user_asset_setting">Geo asset files</string>
|
||||
<string name="title_user_asset_setting">Asset files</string>
|
||||
<string name="title_sort_by_test_results">Sorting by test results</string>
|
||||
<string name="title_filter_config">Filter configuration file</string>
|
||||
<string name="filter_config_all">All groups</string>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:initialLayout="@layout/widget_switch"
|
||||
android:minHeight="20dp"
|
||||
android:minWidth="20dp"
|
||||
android:minHeight="20dp"
|
||||
android:widgetCategory="home_screen|keyguard" />
|
||||
@@ -2,8 +2,9 @@
|
||||
<network-security-config xmlns:tools="http://schemas.android.com/tools">
|
||||
<base-config>
|
||||
<trust-anchors>
|
||||
<certificates src="system"/>
|
||||
<certificates src="user"
|
||||
<certificates src="system" />
|
||||
<certificates
|
||||
src="user"
|
||||
tools:ignore="AcceptsUserCertificates" />
|
||||
</trust-anchors>
|
||||
</base-config>
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package com.v2ray.ang
|
||||
|
||||
import com.v2ray.ang.util.Utils
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
|
||||
@@ -17,7 +17,7 @@ quickieFoss = "1.14.0"
|
||||
kotlinx-coroutines-android = "1.10.1"
|
||||
kotlinx-coroutines-core = "1.10.1"
|
||||
swiperefreshlayout = "1.1.0"
|
||||
toastcompat = "1.1.0"
|
||||
toasty = "1.5.2"
|
||||
editorkit = "2.9.0"
|
||||
core = "3.5.3"
|
||||
workRuntimeKtx = "2.10.0"
|
||||
@@ -44,7 +44,7 @@ gson = { module = "com.google.code.gson:gson", version.ref = "gson" }
|
||||
quickie-foss = { module = "com.github.T8RIN.QuickieExtended:quickie-foss", version.ref = "quickieFoss" }
|
||||
kotlinx-coroutines-android = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-android", version = "kotlinx-coroutines-android" }
|
||||
kotlinx-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version = "kotlinx-coroutines-core" }
|
||||
toastcompat = { module = "me.drakeet.support:toastcompat", version.ref = "toastcompat" }
|
||||
toasty = { module = "com.github.GrenderG:Toasty", version.ref = "toasty" }
|
||||
editorkit = { module = "com.blacksquircle.ui:editorkit", version.ref = "editorkit" }
|
||||
language-base = { module = "com.blacksquircle.ui:language-base", version.ref = "editorkit" }
|
||||
language-json = { module = "com.blacksquircle.ui:language-json", version.ref = "editorkit" }
|
||||
|
||||
Reference in New Issue
Block a user