Add zh-rCN translate

This commit is contained in:
世界
2024-12-14 20:00:39 +08:00
parent 1c494b56a3
commit f8a2783d32
15 changed files with 354 additions and 155 deletions

View File

@@ -11,11 +11,13 @@ import android.net.wifi.WifiManager
import android.os.PowerManager
import androidx.core.content.getSystemService
import go.Seq
import io.nekohasekai.libbox.Libbox
import io.nekohasekai.sfa.bg.AppChangeReceiver
import io.nekohasekai.sfa.bg.UpdateProfileWork
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.util.Locale
import io.nekohasekai.sfa.Application as BoxApplication
class Application : Application() {
@@ -29,6 +31,7 @@ class Application : Application() {
super.onCreate()
Seq.setContext(this)
Libbox.setLocale(Locale.getDefault().toLanguageTag().replace("-", "_"))
@Suppress("OPT_IN_USAGE")
GlobalScope.launch(Dispatchers.IO) {

View File

@@ -1,11 +1,30 @@
package io.nekohasekai.sfa.constant
import android.content.Context
import io.nekohasekai.sfa.R
enum class EnabledType(val boolValue: Boolean) {
Enabled(true), Disabled(false);
fun getString(context: Context): String {
return when (this) {
Enabled -> context.getString(R.string.enabled)
Disabled -> context.getString(R.string.disabled)
}
}
companion object {
fun from(value: Boolean): EnabledType {
return if (value) Enabled else Disabled
}
fun valueOf(context: Context, value: String): EnabledType {
return when (value) {
context.getString(R.string.enabled) -> Enabled
context.getString(R.string.disabled) -> Disabled
else -> Disabled
}
}
}
}

View File

@@ -1,5 +1,7 @@
package io.nekohasekai.sfa.constant
import android.content.Context
import io.nekohasekai.sfa.R
import io.nekohasekai.sfa.database.Settings
enum class PerAppProxyUpdateType {
@@ -11,6 +13,14 @@ enum class PerAppProxyUpdateType {
Deselect -> Settings.PER_APP_PROXY_EXCLUDE
}
fun getString(context: Context): String {
return when (this) {
Disabled -> context.getString(R.string.disabled)
Select -> context.getString(R.string.action_select)
Deselect -> context.getString(R.string.action_deselect)
}
}
companion object {
fun valueOf(value: Int): PerAppProxyUpdateType = when (value) {
Settings.PER_APP_PROXY_DISABLED -> Disabled
@@ -18,5 +28,14 @@ enum class PerAppProxyUpdateType {
Settings.PER_APP_PROXY_EXCLUDE -> Deselect
else -> throw IllegalArgumentException()
}
fun valueOf(context: Context, value: String): PerAppProxyUpdateType {
return when (value) {
context.getString(R.string.disabled) -> Disabled
context.getString(R.string.action_select) -> Select
context.getString(R.string.action_deselect) -> Deselect
else -> Disabled
}
}
}
}

View File

@@ -1,8 +1,11 @@
package io.nekohasekai.sfa.database
import android.content.Context
import android.os.Parcel
import android.os.Parcelable
import androidx.room.TypeConverter
import io.nekohasekai.sfa.R
import io.nekohasekai.sfa.database.TypedProfile.Type.values
import io.nekohasekai.sfa.ktx.marshall
import io.nekohasekai.sfa.ktx.unmarshall
import java.util.Date
@@ -12,6 +15,13 @@ class TypedProfile() : Parcelable {
enum class Type {
Local, Remote;
fun getString(context: Context): String {
return when (this) {
Local -> context.getString(R.string.profile_type_local)
Remote -> context.getString(R.string.profile_type_remote)
}
}
companion object {
fun valueOf(value: Int): Type {
for (it in values()) {

View File

@@ -69,7 +69,7 @@ class SettingsFragment : Fragment() {
}
binding.checkUpdateEnabled.addTextChangedListener {
lifecycleScope.launch(Dispatchers.IO) {
val newValue = EnabledType.valueOf(it).boolValue
val newValue = EnabledType.valueOf(requireContext(), it).boolValue
Settings.checkUpdateEnabled = newValue
}
}
@@ -81,13 +81,13 @@ class SettingsFragment : Fragment() {
}
binding.disableMemoryLimit.addTextChangedListener {
lifecycleScope.launch(Dispatchers.IO) {
val newValue = EnabledType.valueOf(it).boolValue
val newValue = EnabledType.valueOf(requireContext(), it).boolValue
Settings.disableMemoryLimit = !newValue
}
}
binding.dynamicNotificationEnabled.addTextChangedListener {
lifecycleScope.launch(Dispatchers.IO) {
val newValue = EnabledType.valueOf(it).boolValue
val newValue = EnabledType.valueOf(requireContext(), it).boolValue
Settings.dynamicNotification = newValue
}
}
@@ -136,12 +136,15 @@ class SettingsFragment : Fragment() {
val dynamicNotification = Settings.dynamicNotification
withContext(Dispatchers.Main) {
binding.dataSizeText.text = dataSize
binding.checkUpdateEnabled.text = EnabledType.from(checkUpdateEnabled).name
binding.checkUpdateEnabled.text =
EnabledType.from(checkUpdateEnabled).getString(requireContext())
binding.checkUpdateEnabled.setSimpleItems(R.array.enabled)
binding.disableMemoryLimit.text = EnabledType.from(!Settings.disableMemoryLimit).name
binding.disableMemoryLimit.text =
EnabledType.from(!Settings.disableMemoryLimit).getString(requireContext())
binding.disableMemoryLimit.setSimpleItems(R.array.enabled)
binding.backgroundPermissionCard.isGone = removeBackgroundPermissionPage
binding.dynamicNotificationEnabled.text = EnabledType.from(dynamicNotification).name
binding.dynamicNotificationEnabled.text =
EnabledType.from(dynamicNotification).getString(requireContext())
binding.dynamicNotificationEnabled.setSimpleItems(R.array.enabled)
}
}

View File

@@ -67,7 +67,7 @@ class EditProfileActivity : AbstractActivity<ActivityEditProfileBinding>() {
}
}
}
binding.type.text = profile.typed.type.name
binding.type.text = profile.typed.type.getString(this@EditProfileActivity)
binding.editButton.setOnClickListener {
startActivity(
Intent(
@@ -89,7 +89,8 @@ class EditProfileActivity : AbstractActivity<ActivityEditProfileBinding>() {
binding.remoteURL.text = profile.typed.remoteURL
binding.lastUpdated.text =
DateFormat.getDateTimeInstance().format(profile.typed.lastUpdated)
binding.autoUpdate.text = EnabledType.from(profile.typed.autoUpdate).name
binding.autoUpdate.text = EnabledType.from(profile.typed.autoUpdate)
.getString(this@EditProfileActivity)
binding.autoUpdate.setSimpleItems(R.array.enabled)
binding.autoUpdateInterval.isVisible = profile.typed.autoUpdate
binding.autoUpdateInterval.text = profile.typed.autoUpdateInterval.toString()
@@ -111,7 +112,7 @@ class EditProfileActivity : AbstractActivity<ActivityEditProfileBinding>() {
}
private fun updateAutoUpdate(newValue: String) {
val boolValue = EnabledType.valueOf(newValue).boolValue
val boolValue = EnabledType.valueOf(this, newValue).boolValue
if (profile.typed.autoUpdate == boolValue) {
return
}

View File

@@ -1,9 +1,11 @@
package io.nekohasekai.sfa.ui.profile
import android.content.Context
import android.net.Uri
import android.os.Bundle
import android.view.View
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.StringRes
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import io.nekohasekai.libbox.Libbox
@@ -29,9 +31,13 @@ import java.io.InputStream
import java.util.Date
class NewProfileActivity : AbstractActivity<ActivityAddProfileBinding>() {
enum class FileSource(val formatted: String) {
CreateNew("Create New"),
Import("Import");
enum class FileSource(@StringRes val formattedRes: Int) {
CreateNew(R.string.profile_source_create_new),
Import(R.string.profile_source_import);
fun formatted(context: Context): String {
return context.getString(formattedRes)
}
}
private val importFile =
@@ -49,7 +55,7 @@ class NewProfileActivity : AbstractActivity<ActivityAddProfileBinding>() {
intent.getStringExtra("importName")?.also { importName ->
intent.getStringExtra("importURL")?.also { importURL ->
binding.name.editText?.setText(importName)
binding.type.text = TypedProfile.Type.Remote.name
binding.type.text = TypedProfile.Type.Remote.getString(this)
binding.remoteURL.editText?.setText(importURL)
binding.localFields.isVisible = false
binding.remoteFields.isVisible = true
@@ -60,12 +66,12 @@ class NewProfileActivity : AbstractActivity<ActivityAddProfileBinding>() {
binding.name.removeErrorIfNotEmpty()
binding.type.addTextChangedListener {
when (it) {
TypedProfile.Type.Local.name -> {
TypedProfile.Type.Local.getString(this) -> {
binding.localFields.isVisible = true
binding.remoteFields.isVisible = false
}
TypedProfile.Type.Remote.name -> {
TypedProfile.Type.Remote.getString(this) -> {
binding.localFields.isVisible = false
binding.remoteFields.isVisible = true
if (binding.autoUpdateInterval.text.toIntOrNull() == null) {
@@ -76,12 +82,12 @@ class NewProfileActivity : AbstractActivity<ActivityAddProfileBinding>() {
}
binding.fileSourceMenu.addTextChangedListener {
when (it) {
FileSource.CreateNew.formatted -> {
FileSource.CreateNew.formatted(this) -> {
binding.importFileButton.isVisible = false
binding.sourceURL.isVisible = false
}
FileSource.Import.formatted -> {
FileSource.Import.formatted(this) -> {
binding.importFileButton.isVisible = true
binding.sourceURL.isVisible = true
}
@@ -99,9 +105,9 @@ class NewProfileActivity : AbstractActivity<ActivityAddProfileBinding>() {
return
}
when (binding.type.text) {
TypedProfile.Type.Local.name -> {
TypedProfile.Type.Local.getString(this) -> {
when (binding.fileSourceMenu.text) {
FileSource.Import.formatted -> {
FileSource.Import.formatted(this) -> {
if (binding.sourceURL.showErrorIfEmpty()) {
return
}
@@ -109,7 +115,7 @@ class NewProfileActivity : AbstractActivity<ActivityAddProfileBinding>() {
}
}
TypedProfile.Type.Remote.name -> {
TypedProfile.Type.Remote.getString(this) -> {
if (binding.remoteURL.showErrorIfEmpty()) {
return
}
@@ -138,15 +144,15 @@ class NewProfileActivity : AbstractActivity<ActivityAddProfileBinding>() {
typedProfile.path = configFile.path
when (binding.type.text) {
TypedProfile.Type.Local.name -> {
TypedProfile.Type.Local.getString(this) -> {
typedProfile.type = TypedProfile.Type.Local
when (binding.fileSourceMenu.text) {
FileSource.CreateNew.formatted -> {
FileSource.CreateNew.formatted(this) -> {
configFile.writeText("{}")
}
FileSource.Import.formatted -> {
FileSource.Import.formatted(this) -> {
val sourceURL = binding.sourceURL.text
val content = if (sourceURL.startsWith("content://")) {
val inputStream =
@@ -165,7 +171,7 @@ class NewProfileActivity : AbstractActivity<ActivityAddProfileBinding>() {
}
}
TypedProfile.Type.Remote.name -> {
TypedProfile.Type.Remote.getString(this) -> {
typedProfile.type = TypedProfile.Type.Remote
val remoteURL = binding.remoteURL.text
val content = HTTPClient().use { it.getString(remoteURL) }
@@ -173,7 +179,8 @@ class NewProfileActivity : AbstractActivity<ActivityAddProfileBinding>() {
configFile.writeText(content)
typedProfile.remoteURL = remoteURL
typedProfile.lastUpdated = Date()
typedProfile.autoUpdate = EnabledType.valueOf(binding.autoUpdate.text).boolValue
typedProfile.autoUpdate =
EnabledType.valueOf(this, binding.autoUpdate.text).boolValue
binding.autoUpdateInterval.text.toIntOrNull()?.also {
typedProfile.autoUpdateInterval = it
}

View File

@@ -304,7 +304,7 @@ class PerAppProxyActivity : AbstractActivity<ActivityPerAppProxyBinding>() {
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.per_app_menu0, menu)
menuInflater.inflate(R.menu.per_app_menu, menu)
if (menu != null) {
val searchView = menu.findItem(R.id.action_search).actionView as SearchView

View File

@@ -33,7 +33,8 @@ class ProfileOverrideActivity :
binding.perAppProxyUpdateOnChange.addTextChangedListener {
lifecycleScope.launch(Dispatchers.IO) {
Settings.perAppProxyUpdateOnChange = PerAppProxyUpdateType.valueOf(it).value()
Settings.perAppProxyUpdateOnChange =
PerAppProxyUpdateType.valueOf(this@ProfileOverrideActivity, it).value()
}
}
@@ -49,7 +50,8 @@ class ProfileOverrideActivity :
val perAppUpdateOnChange = Settings.perAppProxyUpdateOnChange
withContext(Dispatchers.Main) {
binding.perAppProxyUpdateOnChange.text =
PerAppProxyUpdateType.valueOf(perAppUpdateOnChange).name
PerAppProxyUpdateType.valueOf(perAppUpdateOnChange)
.getString(this@ProfileOverrideActivity)
binding.perAppProxyUpdateOnChange.setSimpleItems(R.array.per_app_proxy_update_on_change_value)
}
}

View File

@@ -4,6 +4,7 @@ import io.nekohasekai.libbox.Libbox
import io.nekohasekai.sfa.BuildConfig
import io.nekohasekai.sfa.ktx.unwrap
import java.io.Closeable
import java.util.Locale
class HTTPClient : Closeable {
@@ -15,6 +16,8 @@ class HTTPClient : Closeable {
userAgent += BuildConfig.VERSION_CODE
userAgent += "; sing-box "
userAgent += Libbox.version()
userAgent += "; language "
userAgent += Locale.getDefault().toLanguageTag().replace("-", "_")
userAgent += ")"
userAgent
}