add zh-cn

This commit is contained in:
Kr328 committed 2020-02-19 13:57:59 +08:00
1 parent 232572114c
commit 168a097111
26 files changed
+142 -56

No files matched your search

@@ -103,7 +103,7 @@ abstract class BaseActivity : AppCompatActivity(), CoroutineScope by MainScope()
if (language.isEmpty())
return super.attachBaseContext(base)
val configuration = base.resources.configuration
val configuration = Configuration()
val localeOverride = if (languageOverride.size == 2)
Locale(languageOverride[0], languageOverride[1])
else
@@ -117,6 +117,8 @@ abstract class BaseActivity : AppCompatActivity(), CoroutineScope by MainScope()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
language = uiSettings.get(UiSettings.LANGUAGE)
resetDarkMode()
resetLightNavigationBar()
@@ -13,6 +13,7 @@ import com.github.kr328.clash.service.ClashService
import com.github.kr328.clash.service.data.ClashProfileEntity
import com.github.kr328.clash.service.util.intent
import com.github.kr328.clash.service.util.startForegroundServiceCompat
import com.github.kr328.clash.utils.startClashService
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
@@ -35,10 +36,8 @@ class MainActivity : BaseActivity() {
if (clashRunning) {
stopService(ClashService::class.intent)
} else {
val vpnRequest = VpnService.prepare(this)
if (vpnRequest == null)
startForegroundServiceCompat(ClashService::class.intent)
else
val vpnRequest = startClashService()
if ( vpnRequest != null )
startActivityForResult(vpnRequest, REQUEST_CODE)
}
}
@@ -2,12 +2,16 @@ package com.github.kr328.clash
import android.app.Application
import android.content.Context
import android.content.res.Configuration
import com.github.kr328.clash.core.Global
import com.github.kr328.clash.core.utils.Log
import com.github.kr328.clash.preference.UiSettings
import com.github.kr328.clash.remote.Broadcasts
import com.github.kr328.clash.remote.Remote
import com.microsoft.appcenter.AppCenter
import com.microsoft.appcenter.analytics.Analytics
import com.microsoft.appcenter.crashes.Crashes
import java.util.*
@Suppress("unused")
class MainApplication : Application() {
@@ -3,9 +3,19 @@ package com.github.kr328.clash
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import com.github.kr328.clash.service.Intents
import com.github.kr328.clash.service.ProfileBackgroundService
import com.github.kr328.clash.service.util.componentName
import com.github.kr328.clash.service.util.startForegroundServiceCompat
import com.github.kr328.clash.utils.startClashService
class OnBootReceiver: BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if ( intent?.action != Intent.ACTION_BOOT_COMPLETED || context == null )
return
context.startClashService()
context.startForegroundServiceCompat(Intent(Intents.INTENT_ACTION_PROFILE_SETUP)
.setComponent(ProfileBackgroundService::class.componentName))
}
}
@@ -294,11 +294,18 @@ class ProxiesActivity : BaseActivity(), ScrollBinding.Callback {
PrefixMerger.Result(p.name, "", p)
}
val data = if ( r.content.isEmpty() ) {
r.prefix to p.type.toString()
}
else {
r.content to r.prefix
}
ProxyAdapter.ProxyInfo(
p.name,
it.name,
r.prefix,
if (r.content.isEmpty()) p.type.toString() else r.content,
data.first,
data.second,
p.delay.toShort(),
it.type == Proxy.Type.SELECT,
p.name == it.current
@@ -2,6 +2,7 @@ package com.github.kr328.clash
import android.os.Bundle
import com.github.kr328.clash.settings.NetworkFragment
import com.google.android.material.snackbar.Snackbar
class SettingsNetworkActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
@@ -13,6 +14,9 @@ class SettingsNetworkActivity : BaseActivity() {
supportFragmentManager.beginTransaction()
.replace(R.id.fragment, NetworkFragment())
.commit()
if ( clashRunning )
Snackbar.make(rootView, R.string.options_unavailable, Snackbar.LENGTH_INDEFINITE).show()
}
override val activityLabel: CharSequence?
@@ -132,6 +132,6 @@ class ProfileAdapter(private val context: Context, private val callback: Callbac
}
private fun offsetDate(date: Long): CharSequence {
return IntervalUtils.intervalString(System.currentTimeMillis() - date)
return IntervalUtils.intervalString(context,System.currentTimeMillis() - date)
}
}
@@ -2,6 +2,7 @@ package com.github.kr328.clash.settings
import com.github.kr328.clash.R
import com.github.kr328.clash.preference.UiSettings
import com.github.kr328.clash.service.settings.ServiceSettings
class InterfaceFragment: BaseSettingFragment() {
companion object {
@@ -15,6 +16,10 @@ class InterfaceFragment: BaseSettingFragment() {
on(KEY_LANGUAGE, UiSettings.LANGUAGE.asSource(ui))
onApply {
service.commit {
put(ServiceSettings.LANGUAGE, ui.get(UiSettings.LANGUAGE))
}
requireActivity().recreate()
}
}
@@ -1,5 +1,7 @@
package com.github.kr328.clash.settings
import android.os.Bundle
import com.github.kr328.clash.BaseActivity
import com.github.kr328.clash.R
import com.github.kr328.clash.preference.UiSettings
import com.github.kr328.clash.service.settings.ServiceSettings
@@ -15,6 +17,13 @@ class NetworkFragment: BaseSettingFragment() {
private const val KEY_ACCESS_CONTROL_MODE = "access_control_mode"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if ((requireActivity() as BaseActivity).clashRunning)
preferenceScreen.isEnabled = false
}
override fun onCreateDataStore(): SettingsDataStore {
return SettingsDataStore().apply {
on(KEY_ENABLE_VPN_SERVICE, UiSettings.ENABLE_VPN.asSource(ui))
@@ -1,5 +1,6 @@
package com.github.kr328.clash.utils
import android.content.Context
import com.github.kr328.clash.R
import com.github.kr328.clash.core.Global
@@ -11,9 +12,7 @@ object IntervalUtils {
private const val MILLIS_MONTH = MILLIS_DAY * 30
private const val MILLIS_YEAR = MILLIS_MONTH * 12
fun intervalString(interval: Long): String {
val context = Global.application
fun intervalString(context: Context, interval: Long): String {
val year = interval / MILLIS_YEAR
val month = interval / MILLIS_MONTH
val day = interval / MILLIS_DAY
@@ -0,0 +1,25 @@
package com.github.kr328.clash.utils
import android.content.Context
import android.content.Intent
import android.net.VpnService
import com.github.kr328.clash.preference.UiSettings
import com.github.kr328.clash.service.ClashService
import com.github.kr328.clash.service.Intents
import com.github.kr328.clash.service.util.intent
import com.github.kr328.clash.service.util.startForegroundServiceCompat
fun Context.startClashService(): Intent? {
val startTun = UiSettings(this).get(UiSettings.ENABLE_VPN)
if ( startTun ) {
val vpnRequest = VpnService.prepare(this)
if ( vpnRequest != null )
return vpnRequest
}
startForegroundServiceCompat(ClashService::class.intent
.putExtra(Intents.INTENT_EXTRA_START_TUN, startTun))
return null
}
-9
View File
@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="?attr/colorOnSurface"
android:pathData="M12,2C6.49,2 2,6.49 2,12s4.49,10 10,10 10,-4.49 10,-10S17.51,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM15,12c0,1.66 -1.34,3 -3,3s-3,-1.34 -3,-3 1.34,-3 3,-3 3,1.34 3,3z"/>
</vector>
+2 -6
View File
@@ -2,7 +2,6 @@
<resources>
<string name="access_control_packages_summary">为应用配置访问权限</string>
<string name="about">关于</string>
<string name="access_control">访问控制</string>
<string name="access_control_mode">访问控制模式</string>
<string name="access_control_packages">访问控制应用包列表</string>
<string name="append_system_dns">追加系统 DNS</string>
@@ -15,7 +14,6 @@
<string name="bypass_private_network">绕过私有网络</string>
<string name="bypass_private_network_summary">绕过私有网络地址</string>
<string name="cancel">取消</string>
<string name="capturing_clash_log">正在捕捉日志</string>
<string name="clash_logcat">Clash 日志捕捉工具</string>
<string name="clash_new_profile">新配置</string>
<string name="clash_start_failure">Clash 启动失败</string>
@@ -42,12 +40,10 @@
<string name="edit_profile">编辑配置</string>
<string name="empty_name">空名称</string>
<string name="enable_ipv6">启用 IPv6 支持 (不建议)</string>
<string name="enabled">已启用</string>
<string name="exit_without_save">退出而不保存</string>
<string name="exit_without_save_warning">所有变更将会丢失</string>
<string name="export">导出</string>
<string name="external">外部</string>
<string name="feedback">反馈</string>
<string name="file">文件</string>
<string name="file_exported">文件已导出</string>
<string name="format_date_time">%s %s</string>
@@ -86,7 +82,7 @@
<string name="profile">配置</string>
<string name="profile_name">配置名称</string>
<string name="profile_url">配置 URL</string>
<string name="profiles">配置文件</string>
<string name="profiles">配置</string>
<string name="properties">参数</string>
<string name="proxy">代理</string>
<string name="recently">近期</string>
@@ -97,7 +93,6 @@
<string name="rule">规则</string>
<string name="rule_mode">规则模式</string>
<string name="running">运行中</string>
<string name="send">发送</string>
<string name="settings">设置</string>
<string name="show_traffic">显示流量</string>
<string name="show_traffic_summary">在通知中自动刷新流量</string>
@@ -114,4 +109,5 @@
<string name="url">URL</string>
<string name="utils">实用工具</string>
<string name="vpn_service">VPN Service</string>
<string name="options_unavailable">选项在 Clash 运行时不可用</string>
</resources>
+2 -5
View File
@@ -18,7 +18,6 @@
<string name="logs">Logs</string>
<string name="settings">Settings</string>
<string name="feedback">Feedback</string>
<string name="support">Support</string>
<string name="about">About</string>
@@ -54,7 +53,6 @@
<string name="edit">Edit</string>
<string name="delete">Delete</string>
<string name="export">Export</string>
<string name="send">Send</string>
<string name="properties">Properties</string>
<string name="duplicate">Duplicate</string>
<string name="reset_provider">Reset Providers</string>
@@ -91,9 +89,7 @@
<string name="cancel">Cancel</string>
<string name="clash_logcat">Clash Logcat</string>
<string name="capturing_clash_log">Capturing logs</string>
<string name="history">History</string>
<string name="enabled">Enabled</string>
<string name="log_viewer">Log Viewer</string>
<string name="format_date_time">%s %s</string>
<string name="format_export_log_name">%s %s.log</string>
@@ -131,11 +127,12 @@
<string name="dns_override_summary">Force use builtin DNS config</string>
<string name="append_system_dns">Append System DNS</string>
<string name="append_system_dns_summary">Auto add system dns to clash</string>
<string name="access_control">Access Control</string>
<string name="access_control_mode">Access Control Mode</string>
<string name="access_control_packages">Access Control Packages</string>
<string name="access_control_packages_summary">Configure access permission for apps</string>
<string name="language">Language</string>
<string name="dark_mode">Dark Mode</string>
<string name="options_unavailable">Options Unavailable until Clash Stopped</string>
</resources>
-9
View File
@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<cache-path
name="export_logs"
path="logs" />
<external-cache-path
name="export_external_logs"
path="logs" />
</paths>
+1
View File
@@ -104,6 +104,7 @@ func parseConfig(data []byte, baseDir string) (*config.Config, error) {
return nil, err
}
raw.Experimental.Interface = ""
raw.ExternalUI = ""
raw.ExternalController = ""
raw.Rule = append([]string{fmt.Sprintf("IP-CIDR,%s,REJECT", tunAddress)}, raw.Rule...)
@@ -1,9 +1,11 @@
package com.github.kr328.clash.core
import android.app.Application
import android.content.res.Configuration
object Global {
lateinit var application: Application
val overrideConfiguration = Configuration()
fun init(application: Application) {
this.application = application
-3
View File
@@ -1,3 +0,0 @@
<resources>
<string name="launch_name">core</string>
</resources>
@@ -1,12 +1,37 @@
package com.github.kr328.clash.service
import android.app.Service
import android.content.Context
import android.content.res.Configuration
import com.github.kr328.clash.core.Clash
import com.github.kr328.clash.service.settings.ServiceSettings
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.cancel
import java.util.*
abstract class BaseService : Service(), CoroutineScope by MainScope() {
lateinit var settings: ServiceSettings
override fun attachBaseContext(base: Context?) {
settings = ServiceSettings(base ?: return super.attachBaseContext(base))
val language = settings.get(ServiceSettings.LANGUAGE)
if ( language.isEmpty() )
return super.attachBaseContext(base)
val languageOverride = language.split("-")
val configuration = Configuration()
val localeOverride = if (languageOverride.size == 2)
Locale(languageOverride[0], languageOverride[1])
else
Locale(languageOverride[0])
configuration.setLocale(localeOverride)
super.attachBaseContext(base.createConfigurationContext(configuration))
}
override fun onCreate() {
super.onCreate()
@@ -63,9 +63,7 @@ class ClashNotification(private val context: ClashService, enableRefresh: Boolea
init {
createNotificationChannel()
runBlocking {
update()
}
notifyBaseNotification()
if (enableRefresh) {
launch {
@@ -133,6 +131,15 @@ class ClashNotification(private val context: ClashService, enableRefresh: Boolea
}
}
private fun notifyBaseNotification() {
val notification = baseBuilder
.setContentTitle(profile)
.setContentText(context.getText(R.string.running))
.build()
context.startForeground(CLASH_STATUS_NOTIFICATION_ID, notification)
}
private suspend fun update() {
val notification = withContext(Dispatchers.Default) {
createNotification()
@@ -18,9 +18,6 @@ import kotlinx.coroutines.sync.Mutex
class ClashService : BaseService() {
companion object {
const val INTENT_EXTRA_START_TUN =
"${BuildConfig.LIBRARY_PACKAGE_NAME}.intent.extra.start.tun"
var isServiceRunning = false
}
@@ -29,7 +26,6 @@ class ClashService : BaseService() {
private lateinit var notification: ClashNotification
private var stopReason: String? = null
private val reloadChannel = Channel<Unit>(Channel.CONFLATED)
private val settings: ServiceSettings by lazy { ServiceSettings(this) }
private val reloadReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if (intent?.`package` != packageName)
@@ -64,7 +60,8 @@ class ClashService : BaseService() {
broadcastClashStarted(this)
val startVpn = intent?.getBooleanExtra(INTENT_EXTRA_START_TUN, true) ?: true
val startVpn = intent?.getBooleanExtra(
Intents.INTENT_EXTRA_START_TUN, true) ?: true
if (startVpn)
startService(TunService::class.intent)
@@ -22,4 +22,6 @@ object Intents {
"${BuildConfig.LIBRARY_PACKAGE_NAME}.intent.extra.profile"
const val INTENT_EXTRA_PROFILE_REQUEST =
"${BuildConfig.LIBRARY_PACKAGE_NAME}.intent.extra.profile.request"
const val INTENT_EXTRA_START_TUN =
"${BuildConfig.LIBRARY_PACKAGE_NAME}.intent.extra.start.tun"
}
@@ -68,8 +68,6 @@ class DefaultNetworkChannel(val context: Context, scope: CoroutineScope) :
return
launch {
delay(1000)
val network = detectDefaultNetwork()
val link = network?.let(connectivity::getLinkProperties)
@@ -12,6 +12,8 @@ class ServiceSettings(context: Context):
const val ACCESS_CONTROL_MODE_BLACKLIST = "access_control_mode_blacklist"
const val ACCESS_CONTROL_MODE_WHITELIST = "access_control_mode_whitelist"
val LANGUAGE =
StringEntry("language", "")
val IPV6_SUPPORT =
BooleanEntry("ipv6_support", false)
val BYPASS_PRIVATE_NETWORK =
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="clash_manager_service_label">Clash 管理器服务</string>
<string name="clash_profile_service_label">Clash 配置管理服务</string>
<string name="clash_service_label">Clash 核心服务</string>
<string name="clash_service_status_channel">Clash 状态</string>
<string name="profile_service_status_channel">配置服务状态</string>
<string name="profile_service_status_title">配置更新工具正在运行</string>
<string name="profile_status_channel">配置处理状态</string>
<string name="profile_status_title">正在处理配置文件</string>
<string name="profile_status_update_completed">更新 %s 完成</string>
<string name="profile_status_update_failure">更新 %s 失败</string>
<string name="profile_status_updating">正在更新 %s</string>
<string name="running">正在运行</string>
<string name="tun_service_label">Tun 服务</string>
</resources>
+3 -3
View File
@@ -1,10 +1,8 @@
<resources>
<string name="launch_name">Clash</string>
<string name="clash_service_status_channel">Clash Status</string>
<!-- from https://github.com/shadowsocks/shadowsocks-android/blob/master/core/src/main/res/values/strings.xml -->
<string name="clash_notification_content">"%1$s↑\t%2$s↓"</string>
<string name="clash_notification_content" translatable="false">"%1$s↑\t%2$s↓"</string>
<string name="profile_service_status_channel">Profile Service Status</string>
<string name="profile_service_status_title">Profile Updater Running</string>
@@ -19,4 +17,6 @@
<string name="tun_service_label">Tun Device Service</string>
<string name="clash_manager_service_label">Clash Manager Service</string>
<string name="clash_profile_service_label">Clash Profile Manager Service</string>
<string name="running">Running</string>
</resources>