refactor: replace toast notifications with temporary status bar messages and update UI styling and typography

This commit is contained in:
zarazaex69
2026-04-04 02:14:44 +03:00
parent 2422b8ea9e
commit 1df3324559
7 changed files with 65 additions and 25 deletions
@@ -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()) {
@@ -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()
@@ -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
}
@@ -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" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
@@ -118,7 +120,9 @@
android:src="@drawable/ic_play_24dp"
app:tint="@color/colorWhite"
app:fabSize="mini"
android:elevation="0dp" />
app:elevation="0dp"
app:pressedTranslationZ="0dp"
app:hoveredFocusedTranslationZ="0dp" />
</LinearLayout>
</LinearLayout>
@@ -23,7 +23,7 @@
<string name="toast_services_failure">Сбой при запуске служб</string>
<!--ServerActivity-->
<string name="title_server">Olcng</string>
<string name="title_server">OlcNG</string>
<string name="menu_item_add_config">Добавить профиль</string>
<string name="menu_item_save_config">Сохранить профиль</string>
<string name="menu_item_edit_config">Изменить профиль</string>
@@ -53,6 +53,23 @@
<!-- Status bar and navigation bar - system bars -->
<item name="android:statusBarColor">@color/md_theme_surface</item>
<item name="android:navigationBarColor">@color/md_theme_surface</item>
<!-- Typography: use Roboto (Google's Material font) everywhere -->
<item name="android:fontFamily">sans-serif</item>
<item name="fontFamily">sans-serif</item>
<item name="android:editTextStyle">@style/RobotoEditTextStyle</item>
<item name="alertDialogTheme">@style/RobotoAlertDialogTheme</item>
<item name="android:dialogTheme">@style/RobotoAlertDialogTheme</item>
</style>
<style name="RobotoEditTextStyle" parent="Widget.AppCompat.EditText">
<item name="android:fontFamily">sans-serif</item>
<item name="android:textSize">16sp</item>
</style>
<style name="RobotoAlertDialogTheme" parent="ThemeOverlay.Material3.MaterialAlertDialog">
<item name="android:fontFamily">sans-serif</item>
<item name="fontFamily">sans-serif</item>
</style>
<!-- Day/Night theme: inherit common values and set light-mode-specific items -->
+1 -1
View File
@@ -13,7 +13,7 @@
## About
olcng - is a free VPN, fork of v2rayNG
olcNG - is a free VPN, fork of v2rayNG
<div align="center">