Optimize and improve

This commit is contained in:
2dust
2025-03-21 16:53:30 +08:00
parent 7a0d997a81
commit 4eb5c0263c
6 changed files with 190 additions and 191 deletions

View File

@@ -11,9 +11,15 @@ class LogcatRecyclerAdapter(val activity: LogcatActivity) : RecyclerView.Adapter
override fun getItemCount() = mActivity.logsets.size
override fun onBindViewHolder(holder: MainViewHolder, position: Int) {
val content = mActivity.logsets[position]
holder.itemSubSettingBinding.logContent.text = content
val log = mActivity.logsets[position]
if (log.isEmpty()) {
holder.itemSubSettingBinding.logTag.text = ""
holder.itemSubSettingBinding.logContent.text = ""
} else {
val content = log.split("):", limit = 2)
holder.itemSubSettingBinding.logTag.text = content.first().trim()
holder.itemSubSettingBinding.logContent.text = if (content.count() > 1) content.last().trim() else ""
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MainViewHolder {

View File

@@ -391,24 +391,8 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
// true
// }
R.id.sub_update -> {
importConfigViaSub()
true
}
R.id.export_all -> {
binding.pbWaiting.show()
lifecycleScope.launch(Dispatchers.IO) {
val ret = mainViewModel.exportAllServer()
launch(Dispatchers.Main) {
if (ret > 0)
toast(getString(R.string.title_export_config_count, ret))
else
toast(R.string.toast_failure)
binding.pbWaiting.hide()
}
}
exportAll()
true
}
@@ -430,77 +414,31 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
}
R.id.del_all_config -> {
AlertDialog.Builder(this).setMessage(R.string.del_config_comfirm)
.setPositiveButton(android.R.string.ok) { _, _ ->
binding.pbWaiting.show()
lifecycleScope.launch(Dispatchers.IO) {
val ret = mainViewModel.removeAllServer()
launch(Dispatchers.Main) {
mainViewModel.reloadServerList()
toast(getString(R.string.title_del_config_count, ret))
binding.pbWaiting.hide()
}
}
}
.setNegativeButton(android.R.string.cancel) { _, _ ->
//do noting
}
.show()
delAllConfig()
true
}
R.id.del_duplicate_config -> {
AlertDialog.Builder(this).setMessage(R.string.del_config_comfirm)
.setPositiveButton(android.R.string.ok) { _, _ ->
binding.pbWaiting.show()
lifecycleScope.launch(Dispatchers.IO) {
val ret = mainViewModel.removeDuplicateServer()
launch(Dispatchers.Main) {
mainViewModel.reloadServerList()
toast(getString(R.string.title_del_duplicate_config_count, ret))
binding.pbWaiting.hide()
}
}
}
.setNegativeButton(android.R.string.cancel) { _, _ ->
//do noting
}
.show()
delDuplicateConfig()
true
}
R.id.del_invalid_config -> {
AlertDialog.Builder(this).setMessage(R.string.del_invalid_config_comfirm)
.setPositiveButton(android.R.string.ok) { _, _ ->
binding.pbWaiting.show()
lifecycleScope.launch(Dispatchers.IO) {
val ret = mainViewModel.removeInvalidServer()
launch(Dispatchers.Main) {
mainViewModel.reloadServerList()
toast(getString(R.string.title_del_config_count, ret))
binding.pbWaiting.hide()
}
}
}
.setNegativeButton(android.R.string.cancel) { _, _ ->
//do noting
}
.show()
delInvalidConfig()
true
}
R.id.sort_by_test_results -> {
binding.pbWaiting.show()
lifecycleScope.launch(Dispatchers.IO) {
mainViewModel.sortByTestResults()
launch(Dispatchers.Main) {
mainViewModel.reloadServerList()
binding.pbWaiting.hide()
}
}
sortByTestResults()
true
}
R.id.sub_update -> {
importConfigViaSub()
true
}
else -> super.onOptionsItemSelected(item)
}
@@ -679,6 +617,88 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
return true
}
private fun exportAll() {
binding.pbWaiting.show()
lifecycleScope.launch(Dispatchers.IO) {
val ret = mainViewModel.exportAllServer()
launch(Dispatchers.Main) {
if (ret > 0)
toast(getString(R.string.title_export_config_count, ret))
else
toast(R.string.toast_failure)
binding.pbWaiting.hide()
}
}
}
private fun delAllConfig() {
AlertDialog.Builder(this).setMessage(R.string.del_config_comfirm)
.setPositiveButton(android.R.string.ok) { _, _ ->
binding.pbWaiting.show()
lifecycleScope.launch(Dispatchers.IO) {
val ret = mainViewModel.removeAllServer()
launch(Dispatchers.Main) {
mainViewModel.reloadServerList()
toast(getString(R.string.title_del_config_count, ret))
binding.pbWaiting.hide()
}
}
}
.setNegativeButton(android.R.string.cancel) { _, _ ->
//do noting
}
.show()
}
private fun delDuplicateConfig() {
AlertDialog.Builder(this).setMessage(R.string.del_config_comfirm)
.setPositiveButton(android.R.string.ok) { _, _ ->
binding.pbWaiting.show()
lifecycleScope.launch(Dispatchers.IO) {
val ret = mainViewModel.removeDuplicateServer()
launch(Dispatchers.Main) {
mainViewModel.reloadServerList()
toast(getString(R.string.title_del_duplicate_config_count, ret))
binding.pbWaiting.hide()
}
}
}
.setNegativeButton(android.R.string.cancel) { _, _ ->
//do noting
}
.show()
}
private fun delInvalidConfig() {
AlertDialog.Builder(this).setMessage(R.string.del_invalid_config_comfirm)
.setPositiveButton(android.R.string.ok) { _, _ ->
binding.pbWaiting.show()
lifecycleScope.launch(Dispatchers.IO) {
val ret = mainViewModel.removeInvalidServer()
launch(Dispatchers.Main) {
mainViewModel.reloadServerList()
toast(getString(R.string.title_del_config_count, ret))
binding.pbWaiting.hide()
}
}
}
.setNegativeButton(android.R.string.cancel) { _, _ ->
//do noting
}
.show()
}
private fun sortByTestResults() {
binding.pbWaiting.show()
lifecycleScope.launch(Dispatchers.IO) {
mainViewModel.sortByTestResults()
launch(Dispatchers.Main) {
mainViewModel.reloadServerList()
binding.pbWaiting.hide()
}
}
}
/**
* show file chooser
*/
@@ -772,37 +792,19 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
override fun onNavigationItemSelected(item: MenuItem): Boolean {
// Handle navigation view item clicks here.
when (item.itemId) {
R.id.sub_setting -> {
requestSubSettingActivity.launch(Intent(this, SubSettingActivity::class.java))
}
R.id.sub_setting -> requestSubSettingActivity.launch(Intent(this, SubSettingActivity::class.java))
R.id.settings -> startActivity(
Intent(this, SettingsActivity::class.java)
.putExtra("isRunning", mainViewModel.isRunning.value == true)
)
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))
}
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))
}
binding.drawerLayout.closeDrawer(GravityCompat.START)
return true
}

View File

@@ -38,7 +38,7 @@ class RoutingSettingActivity : BaseActivity() {
private val preset_rulesets: Array<out String> by lazy {
resources.getStringArray(R.array.preset_rulesets)
}
private val requestCameraPermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { isGranted: Boolean ->
@@ -85,87 +85,75 @@ class RoutingSettingActivity : BaseActivity() {
return super.onCreateOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
R.id.add_rule -> {
startActivity(Intent(this, RoutingEditActivity::class.java))
true
}
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 }
R.id.export_rulesets_to_clipboard -> export2Clipboard().let { true }
else -> super.onOptionsItemSelected(item)
}
R.id.user_asset_setting -> {
startActivity(Intent(this, UserAssetActivity::class.java))
true
}
R.id.import_predefined_rulesets -> {
private fun importPredefined() {
AlertDialog.Builder(this).setItems(preset_rulesets.asList().toTypedArray()) { _, i ->
AlertDialog.Builder(this).setMessage(R.string.routing_settings_import_rulesets_tip)
.setPositiveButton(android.R.string.ok) { _, _ ->
AlertDialog.Builder(this).setItems(preset_rulesets.asList().toTypedArray()) { _, i ->
try {
lifecycleScope.launch(Dispatchers.IO) {
SettingsManager.resetRoutingRulesetsFromPresets(this@RoutingSettingActivity, i)
launch(Dispatchers.Main) {
refreshData()
toast(R.string.toast_success)
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}.show()
}
.setNegativeButton(android.R.string.cancel) { _, _ ->
//do nothing
}
.show()
true
}
R.id.import_rulesets_from_clipboard -> {
AlertDialog.Builder(this).setMessage(R.string.routing_settings_import_rulesets_tip)
.setPositiveButton(android.R.string.ok) { _, _ ->
val clipboard = try {
Utils.getClipboard(this)
} catch (e: Exception) {
e.printStackTrace()
toast(R.string.toast_failure)
return@setPositiveButton
}
lifecycleScope.launch(Dispatchers.IO) {
val result = SettingsManager.resetRoutingRulesets(clipboard)
withContext(Dispatchers.Main) {
if (result) {
try {
lifecycleScope.launch(Dispatchers.IO) {
SettingsManager.resetRoutingRulesetsFromPresets(this@RoutingSettingActivity, i)
launch(Dispatchers.Main) {
refreshData()
toast(R.string.toast_success)
} else {
toast(R.string.toast_failure)
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
.setNegativeButton(android.R.string.cancel) { _, _ ->
//do nothing
}
.show()
true
}
}.show()
}
R.id.import_rulesets_from_qrcode -> {
requestCameraPermissionLauncher.launch(Manifest.permission.CAMERA)
true
}
R.id.export_rulesets_to_clipboard -> {
val rulesetList = MmkvManager.decodeRoutingRulesets()
if (rulesetList.isNullOrEmpty()) {
toast(R.string.toast_failure)
} else {
Utils.setClipboard(this, JsonUtil.toJson(rulesetList))
toast(R.string.toast_success)
private fun importFromClipboard() {
AlertDialog.Builder(this).setMessage(R.string.routing_settings_import_rulesets_tip)
.setPositiveButton(android.R.string.ok) { _, _ ->
val clipboard = try {
Utils.getClipboard(this)
} catch (e: Exception) {
e.printStackTrace()
toast(R.string.toast_failure)
return@setPositiveButton
}
lifecycleScope.launch(Dispatchers.IO) {
val result = SettingsManager.resetRoutingRulesets(clipboard)
withContext(Dispatchers.Main) {
if (result) {
refreshData()
toast(R.string.toast_success)
} else {
toast(R.string.toast_failure)
}
}
}
}
true
}
.setNegativeButton(android.R.string.cancel) { _, _ ->
//do nothing
}
.show()
}
else -> super.onOptionsItemSelected(item)
private fun export2Clipboard() {
val rulesetList = MmkvManager.decodeRoutingRulesets()
if (rulesetList.isNullOrEmpty()) {
toast(R.string.toast_failure)
} else {
Utils.setClipboard(this, JsonUtil.toJson(rulesetList))
toast(R.string.toast_success)
}
}
private val scanQRcodeForRulesets = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {

View File

@@ -7,7 +7,7 @@
android:fitsSystemWindows="true"
tools:context=".ui.RoutingSettingActivity">
<androidx.coordinatorlayout.widget.CoordinatorLayout
<androidx.core.widget.NestedScrollView
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent">
@@ -55,7 +55,8 @@
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:nestedScrollingEnabled="false"
tools:listitem="@layout/item_recycler_routing_setting" />
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.core.widget.NestedScrollView>
</RelativeLayout>

View File

@@ -1,31 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/main_content"
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/pb_waiting"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="wrap_content"
android:indeterminate="true"
android:visibility="invisible"
app:indicatorColor="@color/color_fab_active" />
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/pb_waiting"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true"
android:visibility="invisible"
app:indicatorColor="@color/color_fab_active" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="@layout/item_recycler_sub_setting" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="@layout/item_recycler_sub_setting" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</RelativeLayout>

View File

@@ -13,11 +13,19 @@
android:layout_height="wrap_content"
android:layout_margin="@dimen/margin_spacing_dp8"
android:paddingTop="@dimen/margin_spacing_dp8"
android:orientation="vertical"
android:paddingBottom="@dimen/margin_spacing_dp8">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/log_tag"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.AppCompat.Small" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/log_content"
android:layout_width="match_parent"
android:paddingTop="@dimen/margin_spacing_dp8"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.AppCompat.Small" />