feat(network): socks5 proxy support (#530)
This commit is contained in:
parent
a4bd367f98
commit
ff3372754a
11 changed files with 399 additions and 7 deletions
|
@ -157,7 +157,8 @@
|
|||
android:parentActivityName=".MainActivity" />
|
||||
<activity
|
||||
android:name=".settings.SettingsExtensionsActivity"
|
||||
android:parentActivityName=".MainActivity" />
|
||||
android:parentActivityName=".MainActivity"
|
||||
android:windowSoftInputMode="adjustPan"/>
|
||||
<activity
|
||||
android:name=".settings.SettingsAddonActivity"
|
||||
android:parentActivityName=".MainActivity" />
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
package ani.dantotsu.settings
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import ani.dantotsu.BottomSheetDialogFragment
|
||||
import ani.dantotsu.databinding.BottomSheetProxyBinding
|
||||
import ani.dantotsu.snackString
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.restartApp
|
||||
|
||||
class ProxyDialogFragment : BottomSheetDialogFragment() {
|
||||
private var _binding: BottomSheetProxyBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private var proxyHost: String? = PrefManager.getVal<String>(PrefName.Socks5ProxyHost) ?: ""
|
||||
private var proxyPort: String? = PrefManager.getVal<String>(PrefName.Socks5ProxyPort) ?: ""
|
||||
private var proxyUsername: String? = PrefManager.getVal<String>(PrefName.Socks5ProxyUsername) ?: ""
|
||||
private var proxyPassword: String? = PrefManager.getVal<String>(PrefName.Socks5ProxyPassword) ?: ""
|
||||
private var authEnabled: Boolean = PrefManager.getVal<Boolean>(PrefName.ProxyAuthEnabled)
|
||||
private val proxyEnabled: Boolean = PrefManager.getVal<Boolean>(PrefName.EnableSocks5Proxy)
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
_binding = BottomSheetProxyBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
binding.proxyHost.setText(proxyHost)
|
||||
binding.proxyPort.setText(proxyPort)
|
||||
binding.proxyUsername.setText(proxyUsername)
|
||||
binding.proxyPassword.setText(proxyPassword)
|
||||
binding.proxyAuthentication.isChecked = authEnabled
|
||||
|
||||
binding.proxySave.setOnClickListener {
|
||||
proxyHost = binding.proxyHost.text.toString() ?: ""
|
||||
proxyPort = binding.proxyPort.text.toString() ?: ""
|
||||
proxyUsername = binding.proxyUsername.text.toString() ?: ""
|
||||
proxyPassword = binding.proxyPassword.text.toString() ?: ""
|
||||
|
||||
PrefManager.setVal(PrefName.Socks5ProxyHost, proxyHost)
|
||||
PrefManager.setVal(PrefName.Socks5ProxyPort, proxyPort)
|
||||
PrefManager.setVal(PrefName.Socks5ProxyUsername, proxyUsername)
|
||||
PrefManager.setVal(PrefName.Socks5ProxyPassword, proxyPassword)
|
||||
|
||||
dismiss()
|
||||
if (proxyEnabled) activity?.restartApp()
|
||||
}
|
||||
|
||||
binding.proxyAuthentication.setOnCheckedChangeListener { _, isChecked ->
|
||||
PrefManager.setVal(PrefName.ProxyAuthEnabled, isChecked)
|
||||
binding.proxyUsername.isEnabled = isChecked
|
||||
binding.proxyPassword.isEnabled = isChecked
|
||||
binding.proxyUsernameLayout.isEnabled = isChecked
|
||||
binding.proxyPasswordLayout.isEnabled = isChecked
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
_binding = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
}
|
|
@ -23,9 +23,11 @@ import ani.dantotsu.initActivity
|
|||
import ani.dantotsu.media.MediaType
|
||||
import ani.dantotsu.navBarHeight
|
||||
import ani.dantotsu.parsers.ParserTestActivity
|
||||
import ani.dantotsu.restartApp
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.statusBarHeight
|
||||
import ani.dantotsu.others.CustomBottomDialog
|
||||
import ani.dantotsu.themes.ThemeManager
|
||||
import ani.dantotsu.util.customAlertDialog
|
||||
import eu.kanade.domain.base.BasePreferences
|
||||
|
@ -271,6 +273,26 @@ class SettingsExtensionsActivity : AppCompatActivity() {
|
|||
}
|
||||
),
|
||||
Settings(
|
||||
type = 2,
|
||||
name = getString(R.string.proxy),
|
||||
desc = getString(R.string.proxy_desc),
|
||||
icon = R.drawable.swap_horizontal_circle_24,
|
||||
isChecked = PrefManager.getVal(PrefName.EnableSocks5Proxy),
|
||||
switch = { isChecked, _ ->
|
||||
PrefManager.setVal(PrefName.EnableSocks5Proxy, isChecked)
|
||||
restartApp()
|
||||
}
|
||||
),
|
||||
Settings(
|
||||
type = 1,
|
||||
name = getString(R.string.proxy_setup),
|
||||
desc = getString(R.string.proxy_setup_desc),
|
||||
icon = R.drawable.lan_24,
|
||||
onClick = {
|
||||
ProxyDialogFragment().show(supportFragmentManager, "dialog")
|
||||
}
|
||||
),
|
||||
Settings(
|
||||
type = 2,
|
||||
name = getString(R.string.force_legacy_installer),
|
||||
desc = getString(R.string.force_legacy_installer_desc),
|
||||
|
|
|
@ -47,6 +47,8 @@ enum class PrefName(val data: Pref) { //TODO: Split this into multiple files
|
|||
IncludeMangaList(Pref(Location.General, Boolean::class, true)),
|
||||
AdultOnly(Pref(Location.General, Boolean::class, false)),
|
||||
CommentsEnabled(Pref(Location.General, Int::class, 0)),
|
||||
EnableSocks5Proxy(Pref(Location.General, Boolean::class, false)),
|
||||
ProxyAuthEnabled(Pref(Location.General, Boolean::class, false)),
|
||||
|
||||
//User Interface
|
||||
UseOLED(Pref(Location.UI, Boolean::class, false)),
|
||||
|
@ -197,6 +199,8 @@ enum class PrefName(val data: Pref) { //TODO: Split this into multiple files
|
|||
RefreshStatus(Pref(Location.Irrelevant, Boolean::class, false)),
|
||||
rpcEnabled(Pref(Location.Irrelevant, Boolean::class, true)),
|
||||
|
||||
//testing
|
||||
|
||||
//Protected
|
||||
DiscordToken(Pref(Location.Protected, String::class, "")),
|
||||
DiscordId(Pref(Location.Protected, String::class, "")),
|
||||
|
@ -210,4 +214,8 @@ enum class PrefName(val data: Pref) { //TODO: Split this into multiple files
|
|||
AppPassword(Pref(Location.Protected, String::class, "")),
|
||||
BiometricToken(Pref(Location.Protected, String::class, "")),
|
||||
OverridePassword(Pref(Location.Protected, Boolean::class, false)),
|
||||
Socks5ProxyHost(Pref(Location.Protected, String::class, "")),
|
||||
Socks5ProxyPort(Pref(Location.Protected, String::class, "")),
|
||||
Socks5ProxyUsername(Pref(Location.Protected, String::class, "")),
|
||||
Socks5ProxyPassword(Pref(Location.Protected, String::class, "")),
|
||||
}
|
|
@ -17,11 +17,50 @@ import okhttp3.brotli.BrotliInterceptor
|
|||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
import java.io.File
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.net.InetSocketAddress
|
||||
import java.net.Proxy
|
||||
import java.net.Authenticator
|
||||
import java.net.PasswordAuthentication
|
||||
import java.util.prefs.Preferences
|
||||
import okhttp3.Credentials
|
||||
import okhttp3.Response
|
||||
import okhttp3.Route
|
||||
|
||||
class NetworkHelper(
|
||||
context: Context
|
||||
) {
|
||||
|
||||
init {
|
||||
setupSocks5Proxy()
|
||||
}
|
||||
|
||||
private fun setupSocks5Proxy() {
|
||||
val proxyEnabled = PrefManager.getVal<Boolean>(PrefName.EnableSocks5Proxy)
|
||||
if (proxyEnabled) {
|
||||
val proxyHost = PrefManager.getVal<String>(PrefName.Socks5ProxyHost)
|
||||
val proxyPort = PrefManager.getVal<String>(PrefName.Socks5ProxyPort)
|
||||
|
||||
System.setProperty("socksProxyHost", proxyHost)
|
||||
System.setProperty("socksProxyPort", proxyPort)
|
||||
|
||||
if (PrefManager.getVal<Boolean>(PrefName.ProxyAuthEnabled)) {
|
||||
val proxyUsername = PrefManager.getVal<String>(PrefName.Socks5ProxyUsername)
|
||||
val proxyPassword = PrefManager.getVal<String>(PrefName.Socks5ProxyPassword)
|
||||
|
||||
Authenticator.setDefault(object : Authenticator() {
|
||||
override fun getPasswordAuthentication(): PasswordAuthentication {
|
||||
return PasswordAuthentication(proxyUsername, proxyPassword.toCharArray())
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
} else {
|
||||
System.clearProperty("socksProxyHost")
|
||||
System.clearProperty("socksProxyPort")
|
||||
Authenticator.setDefault(null)
|
||||
}
|
||||
}
|
||||
|
||||
val cookieJar = AndroidCookieJar()
|
||||
|
||||
val client: OkHttpClient = run {
|
||||
|
@ -47,11 +86,9 @@ class NetworkHelper(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (PrefManager.getVal<Boolean>(PrefName.VerboseLogging)) {
|
||||
val httpLoggingInterceptor = HttpLoggingInterceptor(ConsoleLogger()).apply {
|
||||
level = HttpLoggingInterceptor.Level.BASIC
|
||||
|
||||
}
|
||||
builder.addNetworkInterceptor(httpLoggingInterceptor)
|
||||
}
|
||||
|
@ -75,9 +112,8 @@ class NetworkHelper(
|
|||
PREF_DOH_SHECAN -> builder.dohShecan()
|
||||
PREF_DOH_LIBREDNS -> builder.dohLibreDNS()
|
||||
}
|
||||
|
||||
builder.build()
|
||||
}
|
||||
builder.build()
|
||||
}
|
||||
|
||||
val downloadClient = client.newBuilder().callTimeout(20, TimeUnit.MINUTES).build()
|
||||
|
||||
|
@ -103,4 +139,4 @@ class NetworkHelper(
|
|||
companion object {
|
||||
fun defaultUserAgentProvider() = PrefManager.getVal<String>(PrefName.DefaultUserAgent)
|
||||
}
|
||||
}
|
||||
}
|
10
app/src/main/res/drawable/lan_24.xml
Normal file
10
app/src/main/res/drawable/lan_24.xml
Normal file
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M120,880L120,600L240,600L240,440L440,440L440,360L320,360L320,80L640,80L640,360L520,360L520,440L720,440L720,600L840,600L840,880L520,880L520,600L640,600L640,520L320,520L320,600L440,600L440,880L120,880ZM400,280L560,280L560,160L400,160L400,280ZM200,800L360,800L360,680L200,680L200,800ZM600,800L760,800L760,680L600,680L600,800ZM480,280L480,280L480,280L480,280ZM360,680L360,680L360,680L360,680ZM600,680L600,680L600,680L600,680Z"/>
|
||||
</vector>
|
10
app/src/main/res/drawable/network_node_24.xml
Normal file
10
app/src/main/res/drawable/network_node_24.xml
Normal file
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M220,880Q162,880 121,839Q80,798 80,740Q80,682 121,641Q162,600 220,600Q238,600 255,604.5Q272,609 287,617L440,464L440,354Q396,341 368,304.5Q340,268 340,220Q340,162 381,121Q422,80 480,80Q538,80 579,121Q620,162 620,220Q620,268 592,304.5Q564,341 520,354L520,464L674,617Q689,609 705.5,604.5Q722,600 740,600Q798,600 839,641Q880,682 880,740Q880,798 839,839Q798,880 740,880Q682,880 641,839Q600,798 600,740Q600,722 604.5,705Q609,688 617,673L480,536L343,673Q351,688 355.5,705Q360,722 360,740Q360,798 319,839Q278,880 220,880ZM740,800Q765,800 782.5,782.5Q800,765 800,740Q800,715 782.5,697.5Q765,680 740,680Q715,680 697.5,697.5Q680,715 680,740Q680,765 697.5,782.5Q715,800 740,800ZM480,280Q505,280 522.5,262.5Q540,245 540,220Q540,195 522.5,177.5Q505,160 480,160Q455,160 437.5,177.5Q420,195 420,220Q420,245 437.5,262.5Q455,280 480,280ZM220,800Q245,800 262.5,782.5Q280,765 280,740Q280,715 262.5,697.5Q245,680 220,680Q195,680 177.5,697.5Q160,715 160,740Q160,765 177.5,782.5Q195,800 220,800Z"/>
|
||||
</vector>
|
10
app/src/main/res/drawable/swap_horizontal_circle_24.xml
Normal file
10
app/src/main/res/drawable/swap_horizontal_circle_24.xml
Normal file
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M360,720L416,664L354,600L520,600L520,520L354,520L416,456L360,400L200,560L360,720ZM600,560L760,400L600,240L544,296L606,360L440,360L440,440L606,440L544,504L600,560ZM480,880Q397,880 324,848.5Q251,817 197,763Q143,709 111.5,636Q80,563 80,480Q80,397 111.5,324Q143,251 197,197Q251,143 324,111.5Q397,80 480,80Q563,80 636,111.5Q709,143 763,197Q817,251 848.5,324Q880,397 880,480Q880,563 848.5,636Q817,709 763,763Q709,817 636,848.5Q563,880 480,880ZM480,800Q614,800 707,707Q800,614 800,480Q800,346 707,253Q614,160 480,160Q346,160 253,253Q160,346 160,480Q160,614 253,707Q346,800 480,800ZM480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Z"/>
|
||||
</vector>
|
10
app/src/main/res/drawable/vpn_key_24.xml
Normal file
10
app/src/main/res/drawable/vpn_key_24.xml
Normal file
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M280,720Q180,720 110,650Q40,580 40,480Q40,380 110,310Q180,240 280,240Q346,240 401,273Q456,306 488,360L920,360L920,600L840,600L840,720L600,720L600,600L488,600Q456,654 401,687Q346,720 280,720ZM280,640Q346,640 386,599.5Q426,559 434,520L680,520L680,640L760,640L760,520L840,520L840,440L434,440Q426,401 386,360.5Q346,320 280,320Q214,320 167,367Q120,414 120,480Q120,546 167,593Q214,640 280,640ZM280,560Q313,560 336.5,536.5Q360,513 360,480Q360,447 336.5,423.5Q313,400 280,400Q247,400 223.5,423.5Q200,447 200,480Q200,513 223.5,536.5Q247,560 280,560ZM280,480Q280,480 280,480Q280,480 280,480Q280,480 280,480Q280,480 280,480Q280,480 280,480Q280,480 280,480L280,480L280,480L280,480L280,480L280,480L280,480L280,480Q280,480 280,480Q280,480 280,480Z"/>
|
||||
</vector>
|
204
app/src/main/res/layout/bottom_sheet_proxy.xml
Normal file
204
app/src/main/res/layout/bottom_sheet_proxy.xml
Normal file
|
@ -0,0 +1,204 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout 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:id="@+id/proxyLayoutContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bottom_sheet_background">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/proxyLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="32dp"
|
||||
android:visibility="visible">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/proxyTitle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="54dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_weight="1"
|
||||
android:fontFamily="@font/poppins"
|
||||
android:gravity="center_vertical"
|
||||
android:text="@string/socks5"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="16dp">
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/proxyHostLayout"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="56dp"
|
||||
android:layout_weight="5"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:hint="@string/host"
|
||||
app:boxCornerRadiusBottomEnd="16dp"
|
||||
app:boxCornerRadiusBottomStart="16dp"
|
||||
app:boxCornerRadiusTopEnd="16dp"
|
||||
app:boxCornerRadiusTopStart="16dp"
|
||||
app:boxStrokeColor="@color/text_input_layout_stroke_color"
|
||||
app:endIconMode="none"
|
||||
app:hintAnimationEnabled="true"
|
||||
app:startIconDrawable="@drawable/ic_round_dns_24">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/proxyHost"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:fontFamily="@font/poppins_bold"
|
||||
android:inputType="textUri"
|
||||
android:padding="8dp"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textSize="14sp"
|
||||
tools:ignore="LabelFor,TextContrastCheck" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/proxyPortLayout"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="56dp"
|
||||
android:layout_weight="3"
|
||||
android:hint="@string/port"
|
||||
app:boxCornerRadiusBottomEnd="16dp"
|
||||
app:boxCornerRadiusBottomStart="16dp"
|
||||
app:boxCornerRadiusTopEnd="16dp"
|
||||
app:boxCornerRadiusTopStart="16dp"
|
||||
app:boxStrokeColor="@color/text_input_layout_stroke_color"
|
||||
app:endIconMode="none"
|
||||
app:hintAnimationEnabled="true"
|
||||
app:startIconDrawable="@drawable/network_node_24">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/proxyPort"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:fontFamily="@font/poppins_bold"
|
||||
android:inputType="number"
|
||||
android:padding="8dp"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textSize="14sp"
|
||||
tools:ignore="LabelFor,TextContrastCheck" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.checkbox.MaterialCheckBox
|
||||
android:id="@+id/proxyAuthentication"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/poppins_bold"
|
||||
android:layout_marginTop="10dp"
|
||||
android:text="@string/authentication" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/proxyUsernameLayout"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:hint="@string/username"
|
||||
android:enabled="false"
|
||||
app:boxCornerRadiusBottomEnd="16dp"
|
||||
app:boxCornerRadiusBottomStart="16dp"
|
||||
app:boxCornerRadiusTopEnd="16dp"
|
||||
app:boxCornerRadiusTopStart="16dp"
|
||||
app:boxStrokeColor="@color/text_input_layout_stroke_color"
|
||||
app:endIconMode="none"
|
||||
app:hintAnimationEnabled="true"
|
||||
app:startIconDrawable="@drawable/ic_round_person_24">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/proxyUsername"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:fontFamily="@font/poppins_bold"
|
||||
android:inputType="text"
|
||||
android:padding="8dp"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textSize="14sp"
|
||||
android:enabled="false"
|
||||
tools:ignore="LabelFor,TextContrastCheck" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/proxyPasswordLayout"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:hint="@string/password"
|
||||
android:enabled="false"
|
||||
app:boxCornerRadiusBottomEnd="16dp"
|
||||
app:boxCornerRadiusBottomStart="16dp"
|
||||
app:boxCornerRadiusTopEnd="16dp"
|
||||
app:boxCornerRadiusTopStart="16dp"
|
||||
app:boxStrokeColor="@color/text_input_layout_stroke_color"
|
||||
app:endIconMode="password_toggle"
|
||||
app:hintAnimationEnabled="true"
|
||||
app:startIconDrawable="@drawable/vpn_key_24">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/proxyPassword"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:fontFamily="@font/poppins_bold"
|
||||
android:inputType="textPassword"
|
||||
android:padding="8dp"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textSize="14sp"
|
||||
android:enabled="false"
|
||||
tools:ignore="LabelFor,TextContrastCheck" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/proxySave"
|
||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:fontFamily="@font/poppins_bold"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:padding="8dp"
|
||||
android:text="@string/save"
|
||||
android:textSize="16sp"
|
||||
app:cornerRadius="16dp"
|
||||
app:strokeColor="?attr/colorPrimaryContainer" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="4dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="14dp"
|
||||
app:cardBackgroundColor="?attr/colorPrimary"
|
||||
app:cardCornerRadius="2dp"
|
||||
app:cardElevation="0dp" />
|
||||
</FrameLayout>
|
|
@ -1073,6 +1073,16 @@ Non quae tempore quo provident laudantium qui illo dolor vel quia dolor et exerc
|
|||
<string name="private_mode">Private</string>
|
||||
<string name="omega_cursed">you have been Ǫ̴̺̙͎̤̫͓̮̰̿͝M̴͇̤͗́̾̈́̑̍̿̈͌͝Ȅ̴̡̨̛͉̣̙̩̲̣̤̟̪̣̎͗̎̆̒̉͆̆̕ͅͅǴ̸̯̬̗̠̙͛͐̀̈͋̀̈̽́̎̿͘͘͝ͅĀ̶̧̲̀ͅ ̴̢̟͕̜̓̾̓C̶̬̜̰̘̝̱̫͓͙̭̈́͐͋̓̏̈̍̓̀̌̾̚Ư̸̛̤̱̈́͆̽͊͛̐̓́̑͘̕̕͝R̸̨̨͈̬̱̺͕̪̪̘͕͎̂͛́̅̆̓̀͝ͅS̴̨̨̛̩̭̗̹̰̭̥͉̮̝̠̓̔͆̂͊͆̀̈́̅̕͘̚͝È̴̢̛̝͈̳͉͈͒͒̒̄̏̈̈́D̸̢̡̨̜̞̩̼̫̹̗̮͛̀̈̋̾̇̕̕͜ͅ</string>
|
||||
<string name="omega_freed">you have been freed</string>
|
||||
|
||||
<string name="subtitle_langauge">Subtitle Langauge</string>
|
||||
<string name="socks5">SOCKS5</string>
|
||||
<string name="host">Host</string>
|
||||
<string name="port">Port</string>
|
||||
<string name="authentication">Authentication</string>
|
||||
<string name="proxy">Socks5 Proxy</string>
|
||||
<string name="proxy_desc">Route All Your Network Traffic Through a Socks5 Proxy</string>
|
||||
<string name="proxy_setup">Proxy Setup</string>
|
||||
<string name="proxy_setup_desc">Configure your Socks5 Proxy</string>
|
||||
|
||||
|
||||
</resources>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue