fix download assets functionality, fix strings.xml
This commit is contained in:
1 parent
ea816ca981
commit
3aff1800cd
11 files changed
+120
-26
No files matched your search
@@ -21,6 +21,7 @@ import com.v2ray.ang.AppConfig
|
|||||||
import com.v2ray.ang.R
|
import com.v2ray.ang.R
|
||||||
import com.v2ray.ang.databinding.ActivitySubSettingBinding
|
import com.v2ray.ang.databinding.ActivitySubSettingBinding
|
||||||
import com.v2ray.ang.databinding.ItemRecyclerUserAssetBinding
|
import com.v2ray.ang.databinding.ItemRecyclerUserAssetBinding
|
||||||
|
import com.v2ray.ang.dto.AssetUrlItem
|
||||||
import com.v2ray.ang.extension.toTrafficString
|
import com.v2ray.ang.extension.toTrafficString
|
||||||
import com.v2ray.ang.extension.toast
|
import com.v2ray.ang.extension.toast
|
||||||
import com.v2ray.ang.util.MmkvManager
|
import com.v2ray.ang.util.MmkvManager
|
||||||
@@ -39,9 +40,11 @@ import java.util.*
|
|||||||
class UserAssetActivity : BaseActivity() {
|
class UserAssetActivity : BaseActivity() {
|
||||||
private lateinit var binding: ActivitySubSettingBinding
|
private lateinit var binding: ActivitySubSettingBinding
|
||||||
private val settingsStorage by lazy { MMKV.mmkvWithID(MmkvManager.ID_SETTING, MMKV.MULTI_PROCESS_MODE) }
|
private val settingsStorage by lazy { MMKV.mmkvWithID(MmkvManager.ID_SETTING, MMKV.MULTI_PROCESS_MODE) }
|
||||||
|
private val assetStorage by lazy { MMKV.mmkvWithID(MmkvManager.ID_ASSET, MMKV.MULTI_PROCESS_MODE) }
|
||||||
|
|
||||||
val extDir by lazy { File(Utils.userAssetPath(this)) }
|
val extDir by lazy { File(Utils.userAssetPath(this)) }
|
||||||
val geofiles = arrayOf("geosite.dat", "geoip.dat")
|
val builtInGeoFiles = arrayOf("geosite.dat", "geoip.dat")
|
||||||
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@@ -55,6 +58,11 @@ class UserAssetActivity : BaseActivity() {
|
|||||||
binding.recyclerView.adapter = UserAssetAdapter()
|
binding.recyclerView.adapter = UserAssetAdapter()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
binding.recyclerView.adapter?.notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||||
menuInflater.inflate(R.menu.menu_asset, menu)
|
menuInflater.inflate(R.menu.menu_asset, menu)
|
||||||
return super.onCreateOptionsMenu(menu)
|
return super.onCreateOptionsMenu(menu)
|
||||||
@@ -148,31 +156,33 @@ class UserAssetActivity : BaseActivity() {
|
|||||||
val httpPort = Utils.parseInt(settingsStorage?.decodeString(AppConfig.PREF_HTTP_PORT), AppConfig.PORT_HTTP.toInt())
|
val httpPort = Utils.parseInt(settingsStorage?.decodeString(AppConfig.PREF_HTTP_PORT), AppConfig.PORT_HTTP.toInt())
|
||||||
|
|
||||||
toast(R.string.msg_downloading_content)
|
toast(R.string.msg_downloading_content)
|
||||||
geofiles.forEach {
|
var assets = MmkvManager.decodeAssetUrls()
|
||||||
|
assets = addBuiltInGeoItems(assets)
|
||||||
|
|
||||||
|
assets.forEach {
|
||||||
//toast(getString(R.string.msg_downloading_content) + it)
|
//toast(getString(R.string.msg_downloading_content) + it)
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
val result = downloadGeo(it, 60000, httpPort)
|
val result = downloadGeo(it.second, 60000, httpPort)
|
||||||
launch(Dispatchers.Main) {
|
launch(Dispatchers.Main) {
|
||||||
if (result) {
|
if (result) {
|
||||||
toast(getString(R.string.toast_success) + " " + it)
|
toast(getString(R.string.toast_success) + " " + it.second.remarks)
|
||||||
binding.recyclerView.adapter?.notifyDataSetChanged()
|
binding.recyclerView.adapter?.notifyDataSetChanged()
|
||||||
} else {
|
} else {
|
||||||
toast(getString(R.string.toast_failure) + " " + it)
|
toast(getString(R.string.toast_failure) + " " + it.second.remarks)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun downloadGeo(name: String, timeout: Int, httpPort: Int): Boolean {
|
private fun downloadGeo(item: AssetUrlItem, timeout: Int, httpPort: Int): Boolean {
|
||||||
val url = AppConfig.geoUrl + name
|
val targetTemp = File(extDir, item.remarks + "_temp")
|
||||||
val targetTemp = File(extDir, name + "_temp")
|
val target = File(extDir, item.remarks)
|
||||||
val target = File(extDir, name)
|
|
||||||
var conn: HttpURLConnection? = null
|
var conn: HttpURLConnection? = null
|
||||||
//Log.d(AppConfig.ANG_PACKAGE, url)
|
//Log.d(AppConfig.ANG_PACKAGE, url)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
conn = URL(url).openConnection(
|
conn = URL(item.url).openConnection(
|
||||||
Proxy(
|
Proxy(
|
||||||
Proxy.Type.HTTP,
|
Proxy.Type.HTTP,
|
||||||
InetSocketAddress("127.0.0.1", httpPort)
|
InetSocketAddress("127.0.0.1", httpPort)
|
||||||
@@ -197,33 +207,74 @@ class UserAssetActivity : BaseActivity() {
|
|||||||
conn?.disconnect()
|
conn?.disconnect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private fun addBuiltInGeoItems(assets: List<Pair<String, AssetUrlItem>>): List<Pair<String, AssetUrlItem>> {
|
||||||
|
val list = mutableListOf<Pair<String, AssetUrlItem>>()
|
||||||
|
builtInGeoFiles.forEach {
|
||||||
|
list.add(Utils.getUuid() to AssetUrlItem(
|
||||||
|
it,
|
||||||
|
AppConfig.geoUrl + it
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return list + assets
|
||||||
|
}
|
||||||
|
|
||||||
inner class UserAssetAdapter : RecyclerView.Adapter<UserAssetViewHolder>() {
|
inner class UserAssetAdapter : RecyclerView.Adapter<UserAssetViewHolder>() {
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserAssetViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserAssetViewHolder {
|
||||||
return UserAssetViewHolder(ItemRecyclerUserAssetBinding.inflate(LayoutInflater.from(parent.context), parent, false))
|
return UserAssetViewHolder(
|
||||||
|
ItemRecyclerUserAssetBinding.inflate(
|
||||||
|
LayoutInflater.from(parent.context),
|
||||||
|
parent,
|
||||||
|
false)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
override fun onBindViewHolder(holder: UserAssetViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: UserAssetViewHolder, position: Int) {
|
||||||
val file = extDir.listFiles()?.getOrNull(position) ?: return
|
var assets = MmkvManager.decodeAssetUrls();
|
||||||
holder.itemUserAssetBinding.assetName.text = file.name
|
assets = addBuiltInGeoItems(assets);
|
||||||
|
val item = assets.getOrNull(position) ?: return
|
||||||
|
// file with name == item.second.remarks
|
||||||
|
val file = extDir.listFiles()?.find { it.name == item.second.remarks }
|
||||||
|
|
||||||
|
holder.itemUserAssetBinding.assetName.text = item.second.remarks
|
||||||
|
|
||||||
|
if (file != null) {
|
||||||
val dateFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM)
|
val dateFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM)
|
||||||
holder.itemUserAssetBinding.assetProperties.text = "${file.length().toTrafficString()} • ${dateFormat.format(Date(file.lastModified()))}"
|
holder.itemUserAssetBinding.assetProperties.text =
|
||||||
if (file.name in geofiles) {
|
"${file.length().toTrafficString()} • ${dateFormat.format(Date(file.lastModified()))}"
|
||||||
|
} else {
|
||||||
|
holder.itemUserAssetBinding.assetProperties.text = getString(R.string.msg_file_not_found)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.second.remarks in builtInGeoFiles) {
|
||||||
|
holder.itemUserAssetBinding.layoutEdit.visibility = GONE
|
||||||
holder.itemUserAssetBinding.layoutRemove.visibility = GONE
|
holder.itemUserAssetBinding.layoutRemove.visibility = GONE
|
||||||
} else {
|
} else {
|
||||||
|
holder.itemUserAssetBinding.layoutEdit.visibility = VISIBLE
|
||||||
holder.itemUserAssetBinding.layoutRemove.visibility = VISIBLE
|
holder.itemUserAssetBinding.layoutRemove.visibility = VISIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
holder.itemUserAssetBinding.layoutEdit.setOnClickListener {
|
||||||
|
val intent = Intent(this@UserAssetActivity, UserAssetUrlActivity::class.java)
|
||||||
|
intent.putExtra("assetId", item.first)
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
holder.itemUserAssetBinding.layoutRemove.setOnClickListener {
|
holder.itemUserAssetBinding.layoutRemove.setOnClickListener {
|
||||||
file.delete()
|
// file.delete()
|
||||||
|
MmkvManager.removeAssetUrl(item.first)
|
||||||
binding.recyclerView.adapter?.notifyItemRemoved(position)
|
binding.recyclerView.adapter?.notifyItemRemoved(position)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
return extDir.listFiles()?.size ?: 0
|
var assets = MmkvManager.decodeAssetUrls();
|
||||||
|
assets = addBuiltInGeoItems(assets);
|
||||||
|
return assets.size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class UserAssetViewHolder(val itemUserAssetBinding: ItemRecyclerUserAssetBinding) : RecyclerView.ViewHolder(itemUserAssetBinding.root)
|
class UserAssetViewHolder(val itemUserAssetBinding: ItemRecyclerUserAssetBinding) :
|
||||||
|
RecyclerView.ViewHolder(itemUserAssetBinding.root)
|
||||||
}
|
}
|
||||||
@@ -21,7 +21,8 @@ class UserAssetUrlActivity : BaseActivity() {
|
|||||||
var save_config: MenuItem? = null
|
var save_config: MenuItem? = null
|
||||||
|
|
||||||
private val assetStorage by lazy { MMKV.mmkvWithID(MmkvManager.ID_ASSET, MMKV.MULTI_PROCESS_MODE) }
|
private val assetStorage by lazy { MMKV.mmkvWithID(MmkvManager.ID_ASSET, MMKV.MULTI_PROCESS_MODE) }
|
||||||
private val editAssetId by lazy { intent.getStringExtra("assetUrlId").orEmpty() }
|
private val editAssetId by lazy { intent.getStringExtra("assetId").orEmpty() }
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
binding = ActivityUserAssetUrlBinding.inflate(layoutInflater)
|
binding = ActivityUserAssetUrlBinding.inflate(layoutInflater)
|
||||||
@@ -94,7 +95,7 @@ class UserAssetUrlActivity : BaseActivity() {
|
|||||||
if (editAssetId.isNotEmpty()) {
|
if (editAssetId.isNotEmpty()) {
|
||||||
AlertDialog.Builder(this).setMessage(R.string.del_config_comfirm)
|
AlertDialog.Builder(this).setMessage(R.string.del_config_comfirm)
|
||||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||||
MmkvManager.removeSubscription(editAssetId)
|
MmkvManager.removeAssetUrl(editAssetId)
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
.show()
|
.show()
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.v2ray.ang.util
|
|||||||
|
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.tencent.mmkv.MMKV
|
import com.tencent.mmkv.MMKV
|
||||||
|
import com.v2ray.ang.dto.AssetUrlItem
|
||||||
import com.v2ray.ang.dto.ServerAffiliationInfo
|
import com.v2ray.ang.dto.ServerAffiliationInfo
|
||||||
import com.v2ray.ang.dto.ServerConfig
|
import com.v2ray.ang.dto.ServerConfig
|
||||||
import com.v2ray.ang.dto.SubscriptionItem
|
import com.v2ray.ang.dto.SubscriptionItem
|
||||||
@@ -21,6 +22,7 @@ object MmkvManager {
|
|||||||
private val serverStorage by lazy { MMKV.mmkvWithID(ID_SERVER_CONFIG, MMKV.MULTI_PROCESS_MODE) }
|
private val serverStorage by lazy { MMKV.mmkvWithID(ID_SERVER_CONFIG, MMKV.MULTI_PROCESS_MODE) }
|
||||||
private val serverAffStorage by lazy { MMKV.mmkvWithID(ID_SERVER_AFF, MMKV.MULTI_PROCESS_MODE) }
|
private val serverAffStorage by lazy { MMKV.mmkvWithID(ID_SERVER_AFF, MMKV.MULTI_PROCESS_MODE) }
|
||||||
private val subStorage by lazy { MMKV.mmkvWithID(ID_SUB, MMKV.MULTI_PROCESS_MODE) }
|
private val subStorage by lazy { MMKV.mmkvWithID(ID_SUB, MMKV.MULTI_PROCESS_MODE) }
|
||||||
|
private val assetStorage by lazy { MMKV.mmkvWithID(ID_ASSET, MMKV.MULTI_PROCESS_MODE) }
|
||||||
|
|
||||||
fun decodeServerList(): MutableList<String> {
|
fun decodeServerList(): MutableList<String> {
|
||||||
val json = mainStorage?.decodeString(KEY_ANG_CONFIGS)
|
val json = mainStorage?.decodeString(KEY_ANG_CONFIGS)
|
||||||
@@ -143,6 +145,22 @@ object MmkvManager {
|
|||||||
removeServerViaSubid(subid)
|
removeServerViaSubid(subid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun decodeAssetUrls(): List<Pair<String, AssetUrlItem>> {
|
||||||
|
val assetUrlItems = mutableListOf<Pair<String, AssetUrlItem>>()
|
||||||
|
assetStorage?.allKeys()?.forEach { key ->
|
||||||
|
val json = assetStorage?.decodeString(key)
|
||||||
|
if (!json.isNullOrBlank()) {
|
||||||
|
assetUrlItems.add(Pair(key, Gson().fromJson(json, AssetUrlItem::class.java)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assetUrlItems.sortedBy { (_, value) -> value.addedTime }
|
||||||
|
return assetUrlItems
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeAssetUrl(assetid: String) {
|
||||||
|
assetStorage?.remove(assetid)
|
||||||
|
}
|
||||||
|
|
||||||
fun removeAllServer() {
|
fun removeAllServer() {
|
||||||
mainStorage?.clearAll()
|
mainStorage?.clearAll()
|
||||||
serverStorage?.clearAll()
|
serverStorage?.clearAll()
|
||||||
|
|||||||
@@ -42,6 +42,22 @@
|
|||||||
tools:text="1MB . 2020.01.01" />
|
tools:text="1MB . 2020.01.01" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/layout_edit"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/selectableItemBackground"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:padding="@dimen/nav_header_vertical_spacing">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="@dimen/png_height"
|
||||||
|
android:layout_height="@dimen/png_height"
|
||||||
|
app:srcCompat="@drawable/ic_edit_24dp"
|
||||||
|
app:tint="?attr/colorMainText" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/layout_remove"
|
android:id="@+id/layout_remove"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
|||||||
@@ -57,9 +57,6 @@
|
|||||||
<string name="server_lab_security4">المستخدم (اختياري)</string>
|
<string name="server_lab_security4">المستخدم (اختياري)</string>
|
||||||
<string name="server_lab_encryption">التشفير</string>
|
<string name="server_lab_encryption">التشفير</string>
|
||||||
<string name="server_lab_flow">التدفق</string>
|
<string name="server_lab_flow">التدفق</string>
|
||||||
<string name="server_lab_public_key" translatable="false">مفتاح عام</string>
|
|
||||||
<string name="server_lab_short_id" translatable="false">ShortId</string>
|
|
||||||
<string name="server_lab_spider_x" translatable="false">SpiderX</string>
|
|
||||||
<string name="server_lab_reserved">Reserved (اختياري)</string>
|
<string name="server_lab_reserved">Reserved (اختياري)</string>
|
||||||
<string name="server_lab_local_address">العنوان المحلي IPv4(اختياري)</string>
|
<string name="server_lab_local_address">العنوان المحلي IPv4(اختياري)</string>
|
||||||
<string name="server_lab_local_mtu">Mtu(optional, default 1420)</string>
|
<string name="server_lab_local_mtu">Mtu(optional, default 1420)</string>
|
||||||
@@ -82,6 +79,8 @@
|
|||||||
<string name="menu_item_add_file">إضافة ملفات</string>
|
<string name="menu_item_add_file">إضافة ملفات</string>
|
||||||
<string name="menu_item_download_file">تحميل الملفات</string>
|
<string name="menu_item_download_file">تحميل الملفات</string>
|
||||||
<!-- PerAppProxyActivity -->
|
<!-- PerAppProxyActivity -->
|
||||||
|
<string name="title_user_asset_add_url">أضف عنوان URL للأصل</string>
|
||||||
|
<string name="msg_file_not_found">لم يتم العثور على الملف</string>
|
||||||
<string name="msg_dialog_progress">جار التحميل</string>
|
<string name="msg_dialog_progress">جار التحميل</string>
|
||||||
<string name="menu_item_search">بحث</string>
|
<string name="menu_item_search">بحث</string>
|
||||||
<string name="menu_item_select_all">تحديد الكل</string>
|
<string name="menu_item_select_all">تحديد الكل</string>
|
||||||
|
|||||||
@@ -82,6 +82,8 @@
|
|||||||
<string name="menu_item_download_file">دانلود فایلها</string>
|
<string name="menu_item_download_file">دانلود فایلها</string>
|
||||||
|
|
||||||
<!-- PerAppProxyActivity -->
|
<!-- PerAppProxyActivity -->
|
||||||
|
<string name="title_user_asset_add_url">URL را اضافه کنید</string>
|
||||||
|
<string name="msg_file_not_found">فایل پیدا نشد</string>
|
||||||
<string name="msg_dialog_progress">بارگذاری</string>
|
<string name="msg_dialog_progress">بارگذاری</string>
|
||||||
<string name="menu_item_search">جستجو</string>
|
<string name="menu_item_search">جستجو</string>
|
||||||
<string name="menu_item_select_all">انتخاب همه</string>
|
<string name="menu_item_select_all">انتخاب همه</string>
|
||||||
|
|||||||
@@ -49,8 +49,6 @@
|
|||||||
<string name="server_lab_request_host">Запрос узла (WS/H2) / Шифрование QUIC</string>
|
<string name="server_lab_request_host">Запрос узла (WS/H2) / Шифрование QUIC</string>
|
||||||
<string name="server_lab_path">Путь (WS/H2) / Ключ QUIC / Сид KCP / Сервис gRPC</string>
|
<string name="server_lab_path">Путь (WS/H2) / Ключ QUIC / Сид KCP / Сервис gRPC</string>
|
||||||
<string name="server_lab_stream_security">TLS</string>
|
<string name="server_lab_stream_security">TLS</string>
|
||||||
<string name="server_lab_stream_fingerprint" translatable="false">Fingerprint</string>
|
|
||||||
<string name="server_lab_stream_alpn" translatable="false">Alpn</string>
|
|
||||||
<string name="server_lab_allow_insecure">Разрешать небезопасные</string>
|
<string name="server_lab_allow_insecure">Разрешать небезопасные</string>
|
||||||
<string name="server_lab_sni">SNI</string>
|
<string name="server_lab_sni">SNI</string>
|
||||||
<string name="server_lab_address3">Адрес</string>
|
<string name="server_lab_address3">Адрес</string>
|
||||||
@@ -84,6 +82,8 @@
|
|||||||
<string name="menu_item_download_file">Загрузить файлы</string>
|
<string name="menu_item_download_file">Загрузить файлы</string>
|
||||||
|
|
||||||
<!-- PerAppProxyActivity -->
|
<!-- PerAppProxyActivity -->
|
||||||
|
<string name="title_user_asset_add_url">Добавить URL ресурса</string>
|
||||||
|
<string name="msg_file_not_found">Файл не найден</string>
|
||||||
<string name="msg_dialog_progress">Загрузка…</string>
|
<string name="msg_dialog_progress">Загрузка…</string>
|
||||||
<string name="menu_item_search">Поиск</string>
|
<string name="menu_item_search">Поиск</string>
|
||||||
<string name="menu_item_select_all">Выбрать все</string>
|
<string name="menu_item_select_all">Выбрать все</string>
|
||||||
|
|||||||
@@ -82,6 +82,8 @@
|
|||||||
<string name="menu_item_download_file">Tải xuống tệp tin</string>
|
<string name="menu_item_download_file">Tải xuống tệp tin</string>
|
||||||
|
|
||||||
<!-- PerAppProxyActivity -->
|
<!-- PerAppProxyActivity -->
|
||||||
|
<string name="title_user_asset_add_url">Thêm URL nội dung</string>
|
||||||
|
<string name="msg_file_not_found">Không tìm thấy tập tin</string>
|
||||||
<string name="msg_dialog_progress">Đang tải...</string>
|
<string name="msg_dialog_progress">Đang tải...</string>
|
||||||
<string name="menu_item_search">Tìm kiếm</string>
|
<string name="menu_item_search">Tìm kiếm</string>
|
||||||
<string name="menu_item_select_all">Chọn tất cả</string>
|
<string name="menu_item_select_all">Chọn tất cả</string>
|
||||||
|
|||||||
@@ -83,6 +83,8 @@
|
|||||||
|
|
||||||
|
|
||||||
<!-- PerAppProxyActivity -->
|
<!-- PerAppProxyActivity -->
|
||||||
|
<string name="title_user_asset_add_url">添加资产网址</string>
|
||||||
|
<string name="msg_file_not_found">文件未找到</string>
|
||||||
<string name="msg_dialog_progress">正在加载</string>
|
<string name="msg_dialog_progress">正在加载</string>
|
||||||
<string name="menu_item_search">搜索</string>
|
<string name="menu_item_search">搜索</string>
|
||||||
<string name="menu_item_select_all">全选</string>
|
<string name="menu_item_select_all">全选</string>
|
||||||
|
|||||||
@@ -82,6 +82,8 @@
|
|||||||
<string name="menu_item_download_file">下載檔案</string>
|
<string name="menu_item_download_file">下載檔案</string>
|
||||||
|
|
||||||
<!-- PerAppProxyActivity -->
|
<!-- PerAppProxyActivity -->
|
||||||
|
<string name="title_user_asset_add_url">新增資產網址</string>
|
||||||
|
<string name="msg_file_not_found">文件未找到</string>
|
||||||
<string name="msg_dialog_progress">載入</string>
|
<string name="msg_dialog_progress">載入</string>
|
||||||
<string name="menu_item_search">搜尋</string>
|
<string name="menu_item_search">搜尋</string>
|
||||||
<string name="menu_item_select_all">全選</string>
|
<string name="menu_item_select_all">全選</string>
|
||||||
|
|||||||
@@ -90,7 +90,8 @@
|
|||||||
<string name="menu_item_add_url">Add URL</string>
|
<string name="menu_item_add_url">Add URL</string>
|
||||||
<string name="title_url" translatable="false">URL</string>
|
<string name="title_url" translatable="false">URL</string>
|
||||||
<string name="menu_item_download_file">Download files</string>
|
<string name="menu_item_download_file">Download files</string>
|
||||||
<string name="title_user_asset_add_url" translatable="false">Add asset URL</string>
|
<string name="title_user_asset_add_url">Add asset URL</string>
|
||||||
|
<string name="msg_file_not_found">File not found</string>
|
||||||
|
|
||||||
|
|
||||||
<!-- PerAppProxyActivity -->
|
<!-- PerAppProxyActivity -->
|
||||||
|
|||||||
Reference in new issue
Block a user