diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/AngApplication.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/AngApplication.kt index 1e5beaca..8b3f2aa7 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/AngApplication.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/AngApplication.kt @@ -4,6 +4,7 @@ import android.content.Context import androidx.multidex.MultiDexApplication import androidx.work.Configuration import androidx.work.WorkManager +import com.google.android.material.color.DynamicColors import com.tencent.mmkv.MMKV import com.v2ray.ang.AppConfig.ANG_PACKAGE import com.v2ray.ang.handler.SettingsManager @@ -31,6 +32,8 @@ class AngApplication : MultiDexApplication() { */ override fun onCreate() { super.onCreate() + // Apply Material You dynamic colors (Android 12+) + DynamicColors.applyToActivitiesIfAvailable(this) val mmkvDir = java.io.File(filesDir, "mmkv") if (!java.io.File(mmkvDir, "MAIN").exists()) { diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2RayServiceManager.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2RayServiceManager.kt index 891f86bf..49a7b4fc 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2RayServiceManager.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2RayServiceManager.kt @@ -122,9 +122,7 @@ object V2RayServiceManager { // if (!result.status) return if (MmkvManager.decodeSettingsBool(AppConfig.PREF_PROXY_SHARING)) { - context.toast(R.string.toast_warning_pref_proxysharing_short) - } else { - context.toast(R.string.toast_services_start) + Log.i(AppConfig.TAG, "StartCore-Manager: proxy sharing enabled") } val isVpnMode = SettingsManager.isVpnMode() diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/MainActivity.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/MainActivity.kt index 3172095e..4d8dd7c6 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/MainActivity.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/MainActivity.kt @@ -155,10 +155,10 @@ class MainActivity : HelperBaseActivity(), NavigationView.OnNavigationItemSelect val firstServer = mainViewModel.serversCache.firstOrNull() if (firstServer != null) { MmkvManager.setSelectServer(firstServer.guid) - toast("Подключаемся к быстрейшему серверу") + showStatus("Подключаемся к быстрейшему серверу") startV2RayWithPermission() } else { - toast("Серверы не найдены!") + showStatus("Серверы не найдены!") } } } @@ -211,7 +211,7 @@ class MainActivity : HelperBaseActivity(), NavigationView.OnNavigationItemSelect V2RayServiceManager.stopVService(this) } - toast("Выполняется замер задержки. Ожидаем завершения...") + showStatus("Выполняется замер задержки. Ожидаем завершения...") isLiteTesting = true mainViewModel.testAllRealPing() } @@ -231,7 +231,7 @@ class MainActivity : HelperBaseActivity(), NavigationView.OnNavigationItemSelect private fun startV2Ray() { if (MmkvManager.getSelectServer().isNullOrEmpty()) { - toast(R.string.title_file_chooser) + showStatus(R.string.title_file_chooser) return } V2RayServiceManager.startVService(this) @@ -247,10 +247,28 @@ class MainActivity : HelperBaseActivity(), NavigationView.OnNavigationItemSelect } } + private var statusResetJob: kotlinx.coroutines.Job? = null + private fun setTestState(content: String?) { binding.tvTestState.text = content } + /** Show a temporary message in the status bar, then revert to connection state */ + private fun showStatus(message: String) { + statusResetJob?.cancel() + binding.tvTestState.text = message + statusResetJob = lifecycleScope.launch { + delay(3000) + val isRunning = mainViewModel.isRunning.value == true + binding.tvTestState.text = getString( + if (isRunning) R.string.connection_connected + else R.string.connection_not_connected + ) + } + } + + private fun showStatus(resId: Int) = showStatus(getString(resId)) + private fun applyRunningState(isLoading: Boolean, isRunning: Boolean) { if (isLoading) { binding.fab.setImageResource(R.drawable.ic_fab_check) @@ -291,7 +309,7 @@ class MainActivity : HelperBaseActivity(), NavigationView.OnNavigationItemSelect R.id.real_ping_all -> { - toast(getString(R.string.connection_test_testing_count, mainViewModel.serversCache.count())) + showStatus(getString(R.string.connection_test_testing_count, mainViewModel.serversCache.count())) mainViewModel.testAllRealPing() true } @@ -358,18 +376,18 @@ class MainActivity : HelperBaseActivity(), NavigationView.OnNavigationItemSelect withContext(Dispatchers.Main) { when { count > 0 -> { - toast(getString(R.string.title_import_config_count, count)) + showStatus(getString(R.string.title_import_config_count, count)) mainViewModel.reloadServerList() } countSub > 0 -> setupGroupTab() - else -> toastError(R.string.toast_failure) + else -> showStatus(getString(R.string.toast_failure)) } hideLoading() } } catch (e: Exception) { withContext(Dispatchers.Main) { - toastError(R.string.toast_failure) + showStatus(getString(R.string.toast_failure)) hideLoading() } Log.e(AppConfig.TAG, "Failed to import batch config", e) @@ -402,11 +420,11 @@ class MainActivity : HelperBaseActivity(), NavigationView.OnNavigationItemSelect delay(500L) launch(Dispatchers.Main) { if (result.successCount + result.failureCount + result.skipCount == 0) { - toast(R.string.title_update_subscription_no_subscription) + showStatus(R.string.title_update_subscription_no_subscription) } else if (result.successCount > 0 && result.failureCount + result.skipCount == 0) { - toast(getString(R.string.title_update_config_count, result.configCount)) + showStatus(getString(R.string.title_update_config_count, result.configCount)) } else { - toast( + showStatus( getString( R.string.title_update_subscription_result, result.configCount, result.successCount, result.failureCount, result.skipCount @@ -428,9 +446,9 @@ class MainActivity : HelperBaseActivity(), NavigationView.OnNavigationItemSelect val ret = mainViewModel.exportAllServer() launch(Dispatchers.Main) { if (ret > 0) - toast(getString(R.string.title_export_config_count, ret)) + showStatus(getString(R.string.title_export_config_count, ret)) else - toastError(R.string.toast_failure) + showStatus(getString(R.string.toast_failure)) hideLoading() } } @@ -444,7 +462,7 @@ class MainActivity : HelperBaseActivity(), NavigationView.OnNavigationItemSelect val ret = mainViewModel.removeAllServer() launch(Dispatchers.Main) { mainViewModel.reloadServerList() - toast(getString(R.string.title_del_config_count, ret)) + showStatus(getString(R.string.title_del_config_count, ret)) hideLoading() } } @@ -463,7 +481,7 @@ class MainActivity : HelperBaseActivity(), NavigationView.OnNavigationItemSelect val ret = mainViewModel.removeDuplicateServer() launch(Dispatchers.Main) { mainViewModel.reloadServerList() - toast(getString(R.string.title_del_duplicate_config_count, ret)) + showStatus(getString(R.string.title_del_duplicate_config_count, ret)) hideLoading() } } @@ -482,7 +500,7 @@ class MainActivity : HelperBaseActivity(), NavigationView.OnNavigationItemSelect val ret = mainViewModel.removeInvalidServer() launch(Dispatchers.Main) { mainViewModel.reloadServerList() - toast(getString(R.string.title_del_config_count, ret)) + showStatus(getString(R.string.title_del_config_count, ret)) hideLoading() } } @@ -537,13 +555,13 @@ class MainActivity : HelperBaseActivity(), NavigationView.OnNavigationItemSelect private fun locateSelectedServer() { val targetSubscriptionId = mainViewModel.findSubscriptionIdBySelect() if (targetSubscriptionId.isNullOrEmpty()) { - toast(R.string.title_file_chooser) + showStatus(R.string.title_file_chooser) return } val targetGroupIndex = groupPagerAdapter.groups.indexOfFirst { it.id == targetSubscriptionId } if (targetGroupIndex < 0) { - toast(R.string.toast_server_not_found_in_group) + showStatus(R.string.toast_server_not_found_in_group) return } diff --git a/V2rayNG/app/src/main/res/layout/activity_main.xml b/V2rayNG/app/src/main/res/layout/activity_main.xml index ca124f38..7ca17d2a 100644 --- a/V2rayNG/app/src/main/res/layout/activity_main.xml +++ b/V2rayNG/app/src/main/res/layout/activity_main.xml @@ -104,7 +104,9 @@ app:backgroundTint="@color/color_fab_inactive" app:fabSize="mini" app:maxImageSize="24dp" - android:elevation="0dp" /> + app:elevation="0dp" + app:pressedTranslationZ="0dp" + app:hoveredFocusedTranslationZ="0dp" /> + app:elevation="0dp" + app:pressedTranslationZ="0dp" + app:hoveredFocusedTranslationZ="0dp" /> diff --git a/V2rayNG/app/src/main/res/values-ru/strings.xml b/V2rayNG/app/src/main/res/values-ru/strings.xml index 2e259568..4c824314 100644 --- a/V2rayNG/app/src/main/res/values-ru/strings.xml +++ b/V2rayNG/app/src/main/res/values-ru/strings.xml @@ -23,7 +23,7 @@ Сбой при запуске служб - Olcng + OlcNG Добавить профиль Сохранить профиль Изменить профиль diff --git a/V2rayNG/app/src/main/res/values/themes.xml b/V2rayNG/app/src/main/res/values/themes.xml index 44cbc0eb..ee899140 100644 --- a/V2rayNG/app/src/main/res/values/themes.xml +++ b/V2rayNG/app/src/main/res/values/themes.xml @@ -53,6 +53,23 @@ @color/md_theme_surface @color/md_theme_surface + + + sans-serif + sans-serif + @style/RobotoEditTextStyle + @style/RobotoAlertDialogTheme + @style/RobotoAlertDialogTheme + + + + + diff --git a/readme.md b/readme.md index 63b6532c..906418f5 100644 --- a/readme.md +++ b/readme.md @@ -13,7 +13,7 @@ ## About -olcng - is a free VPN, fork of v2rayNG +olcNG - is a free VPN, fork of v2rayNG