Skip to content

Commit b8e23f0

Browse files
fix(traffic): keep total traffic chip persistent across server deletion
1 parent 881b338 commit b8e23f0

10 files changed

Lines changed: 155 additions & 23 deletions

File tree

V2rayNG/app/src/main/java/com/v2ray/ang/AppConfig.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ object AppConfig {
180180
const val WEATHER_LOCATION_TIMEOUT_MS = 10_000L
181181
const val WEATHER_LOCATION_STALE_METERS = 5_000f
182182
const val PREF_SHOW_TOTAL_TRAFFIC_CHIP = "pref_show_total_traffic_chip"
183+
const val PREF_ACTION_CLEAR_TOTAL_TRAFFIC = "action_clear_total_traffic"
183184
const val PREF_SEARCH_CHIP_GRADIENT = "pref_search_chip_gradient"
184185
const val PREF_SHOW_REALTIME_TRAFFIC_IP = "pref_show_realtime_traffic_ip"
185186

V2rayNG/app/src/main/java/com/v2ray/ang/handler/MmkvManager.kt

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ object MmkvManager {
3737
private const val ID_SETTING = "SETTING"
3838
private const val ID_DAILY_TRAFFIC = "DAILY_TRAFFIC"
3939
private const val KEY_DAILY_TRAFFIC_DATES = "DAILY_TRAFFIC_DATES"
40+
private const val KEY_TOTAL_TRAFFIC_UPLINK = "TOTAL_TRAFFIC_UPLINK_ALL_TIME"
41+
private const val KEY_TOTAL_TRAFFIC_DOWNLINK = "TOTAL_TRAFFIC_DOWNLINK_ALL_TIME"
4042
private const val DAILY_TRAFFIC_RETENTION_DAYS = 90
4143
private const val KEY_SELECTED_SERVER = "SELECTED_SERVER"
4244
private const val KEY_ANG_CONFIGS = "ANG_CONFIGS"
@@ -421,26 +423,63 @@ object MmkvManager {
421423

422424
fun resetAllTraffic() {
423425
decodeAllServerList().forEach { guid -> resetProfileTraffic(guid) }
424-
dailyTrafficStorage.clearAll()
426+
clearDailyTrafficHistory()
425427
}
426428

427429
fun getTotalTrafficString(): String? {
428430
val (uplinkTotal, downlinkTotal) = getTotalTrafficDetail() ?: return null
429431
return formatTrafficBytes(uplinkTotal + downlinkTotal)
430432
}
431433

434+
/**
435+
* All-time total traffic, kept as its own running counter (in [dailyTrafficStorage]) so it
436+
* survives server deletions/imports. This is no longer derived by summing the live server
437+
* list's per-profile traffic - it only grows via [addTotalTrafficAllTime]. It is untouched by
438+
* [resetAllTraffic] (the server list's "Reset traffic" menu); it only shrinks via the explicit
439+
* [clearTotalTrafficDataAndHistory] call wired to the "Clear total traffic data" preference.
440+
*/
432441
fun getTotalTrafficDetail(): Pair<Long, Long>? {
433-
var uplinkTotal = 0L
434-
var downlinkTotal = 0L
435-
decodeAllServerList().forEach { guid ->
436-
val aff = decodeServerAffiliationInfo(guid) ?: return@forEach
437-
uplinkTotal += aff.uplinkTotal
438-
downlinkTotal += aff.downlinkTotal
439-
}
442+
val uplinkTotal = dailyTrafficStorage.decodeLong(KEY_TOTAL_TRAFFIC_UPLINK, 0L)
443+
val downlinkTotal = dailyTrafficStorage.decodeLong(KEY_TOTAL_TRAFFIC_DOWNLINK, 0L)
440444
if (uplinkTotal + downlinkTotal == 0L) return null
441445
return uplinkTotal to downlinkTotal
442446
}
443447

448+
/**
449+
* Called from TrafficController on every traffic tick to accumulate the all-time total.
450+
* Only invoked while the "Show total traffic usage chip" preference is enabled, so nothing
451+
* is counted here when the chip is off.
452+
*/
453+
fun addTotalTrafficAllTime(uplink: Long, downlink: Long) {
454+
if (uplink == 0L && downlink == 0L) return
455+
val newUplinkTotal = dailyTrafficStorage.decodeLong(KEY_TOTAL_TRAFFIC_UPLINK, 0L) + uplink
456+
val newDownlinkTotal = dailyTrafficStorage.decodeLong(KEY_TOTAL_TRAFFIC_DOWNLINK, 0L) + downlink
457+
dailyTrafficStorage.encode(KEY_TOTAL_TRAFFIC_UPLINK, newUplinkTotal)
458+
dailyTrafficStorage.encode(KEY_TOTAL_TRAFFIC_DOWNLINK, newDownlinkTotal)
459+
}
460+
461+
private fun clearTotalTrafficAllTime() {
462+
dailyTrafficStorage.remove(KEY_TOTAL_TRAFFIC_UPLINK)
463+
dailyTrafficStorage.remove(KEY_TOTAL_TRAFFIC_DOWNLINK)
464+
}
465+
466+
/** Wipes just the recorded daily/monthly traffic history (today, this month, history list). */
467+
private fun clearDailyTrafficHistory() {
468+
decodeDailyTrafficDates().forEach { dailyTrafficStorage.removeValueForKey(it) }
469+
dailyTrafficStorage.remove(KEY_DAILY_TRAFFIC_DATES)
470+
}
471+
472+
/**
473+
* Clears everything backing the total traffic chip: the all-time counter shown on the chip
474+
* itself, plus the daily/monthly history shown in its detail dialog. Does not touch any
475+
* individual server's own traffic counter - that's reset separately via the server list's
476+
* "Reset traffic" menu (resetProfileTraffic / resetGroupTraffic / resetAllTraffic).
477+
*/
478+
fun clearTotalTrafficDataAndHistory() {
479+
clearTotalTrafficAllTime()
480+
clearDailyTrafficHistory()
481+
}
482+
444483
private fun dailyTrafficDateKey(calendar: java.util.Calendar): String {
445484
val fmt = java.text.SimpleDateFormat("yyyy-MM-dd", java.util.Locale.US)
446485
fmt.timeZone = calendar.timeZone
@@ -461,7 +500,11 @@ object MmkvManager {
461500
dailyTrafficStorage.encode(KEY_DAILY_TRAFFIC_DATES, JsonUtil.toJson(dates))
462501
}
463502

464-
/** Called from TrafficController on every traffic tick to accumulate today's usage. */
503+
/**
504+
* Called from TrafficController on every traffic tick to accumulate today's usage. Only
505+
* invoked while the "Show total traffic usage chip" preference is enabled - this history
506+
* backs that chip's detail dialog and is independent of any per-server traffic.
507+
*/
465508
fun addDailyTraffic(uplink: Long, downlink: Long) {
466509
if (uplink == 0L && downlink == 0L) return
467510
val todayKey = dailyTrafficDateKey(java.util.Calendar.getInstance())

V2rayNG/app/src/main/java/com/v2ray/ang/handler/TrafficController.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,11 @@ object TrafficController {
108108

109109
val guid = MmkvManager.getSelectServer() ?: return
110110
MmkvManager.addProfileTraffic(guid, proxyUplink, proxyDownlink)
111-
MmkvManager.addDailyTraffic(proxyUplink, proxyDownlink)
111+
112+
if (MmkvManager.decodeSettingsBool(AppConfig.PREF_SHOW_TOTAL_TRAFFIC_CHIP, false) == true) {
113+
MmkvManager.addDailyTraffic(proxyUplink, proxyDownlink)
114+
MmkvManager.addTotalTrafficAllTime(proxyUplink, proxyDownlink)
115+
}
112116

113117
getService()?.let { svc ->
114118
MessageUtil.sendMsg2UI(svc, AppConfig.MSG_TRAFFIC_UPDATED, guid)

V2rayNG/app/src/main/java/com/v2ray/ang/ui/preference/activity/UiSettingsActivity.kt

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ class UiSettingsActivity : BaseActivity() {
123123
private val weatherUnit by lazy { findPreference<ListPreference>(AppConfig.PREF_WEATHER_USE_CELSIUS) }
124124
private val weatherCustomLocation by lazy { findPreference<EditTextPreference>(AppConfig.PREF_WEATHER_CUSTOM_LOCATION) }
125125
private val showTotalTrafficChip by lazy { findPreference<SwitchPreferenceCompat>(AppConfig.PREF_SHOW_TOTAL_TRAFFIC_CHIP) }
126+
private val clearTotalTraffic by lazy { findPreference<Preference>(AppConfig.PREF_ACTION_CLEAR_TOTAL_TRAFFIC) }
126127
private val searchChipGradient by lazy { findPreference<SwitchPreferenceCompat>(AppConfig.PREF_SEARCH_CHIP_GRADIENT) }
127128
private val toolbarCenterSubtitleMode by lazy { findPreference<SwitchPreferenceCompat>(AppConfig.PREF_TOOLBAR_CENTER_SUBTITLE_MODE) }
128129
private val showRealtimeTrafficIp by lazy { findPreference<SwitchPreferenceCompat>(AppConfig.PREF_SHOW_REALTIME_TRAFFIC_IP) }
@@ -535,6 +536,27 @@ class UiSettingsActivity : BaseActivity() {
535536
MmkvManager.encodeSettings(AppConfig.PREF_SHOW_TOTAL_TRAFFIC_CHIP, checked)
536537
showWeatherChip?.isEnabled = !checked
537538
searchChipGradient?.isEnabled = checked || (showWeatherChip?.isChecked == true)
539+
updateClearTotalTrafficSummary(chipOnOverride = checked)
540+
true
541+
}
542+
543+
updateClearTotalTrafficSummary()
544+
clearTotalTraffic?.setOnPreferenceClickListener {
545+
if (MmkvManager.getTotalTrafficDetail() == null) {
546+
requireContext().toastInfo(getString(R.string.pref_action_clear_total_traffic_summary_empty))
547+
return@setOnPreferenceClickListener true
548+
}
549+
MaterialAlertDialogBuilder(requireContext())
550+
.setTitle(R.string.pref_action_clear_total_traffic_title)
551+
.setIcon(RemixR.drawable.rmx_delete_bin_line)
552+
.setMessage(R.string.confirm_clear_total_traffic)
553+
.setPositiveButton(android.R.string.ok) { _, _ ->
554+
MmkvManager.clearTotalTrafficDataAndHistory()
555+
updateClearTotalTrafficSummary()
556+
requireContext().snackbarSuccess(getString(R.string.toast_total_traffic_cleared), title = getString(R.string.title_alerter_success))
557+
}
558+
.setNegativeButton(android.R.string.cancel, null)
559+
.showBlur()
538560
true
539561
}
540562

@@ -693,6 +715,29 @@ class UiSettingsActivity : BaseActivity() {
693715
}
694716
}
695717

718+
private fun updateClearTotalTrafficSummary(chipOnOverride: Boolean? = null) {
719+
val chipOn = chipOnOverride ?: (showTotalTrafficChip?.isChecked == true)
720+
val detail = MmkvManager.getTotalTrafficDetail()
721+
clearTotalTraffic?.apply {
722+
if (!chipOn) {
723+
isEnabled = false
724+
summary = getString(
725+
R.string.summary_pref_action_clear_total_traffic_disabled,
726+
getString(R.string.pref_show_total_traffic_chip_title)
727+
)
728+
return@apply
729+
}
730+
isEnabled = detail != null
731+
summary = if (detail != null) {
732+
val (uplink, downlink) = detail
733+
val totalText = MmkvManager.formatTrafficBytesPublic(uplink + downlink)
734+
getString(R.string.pref_action_clear_total_traffic_summary_set, totalText)
735+
} else {
736+
getString(R.string.pref_action_clear_total_traffic_summary_empty)
737+
}
738+
}
739+
}
740+
696741
private fun queryDisplayName(uri: Uri): String? {
697742
return try {
698743
requireContext().contentResolver.query(uri, null, null, null, null)?.use { cursor ->

V2rayNG/app/src/main/res/layout/dialog_total_traffic_detail.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@
256256
android:layout_width="wrap_content"
257257
android:layout_height="wrap_content"
258258
android:layout_marginEnd="10dp"
259-
android:text="@string/label_total_traffic_upload"
259+
android:text="@string/label_total_traffic_up"
260260
android:textAppearance="?attr/textAppearanceBodySmall"
261261
android:textColor="?attr/colorOnSurfaceVariant" />
262262

@@ -270,7 +270,7 @@
270270
<com.google.android.material.textview.MaterialTextView
271271
android:layout_width="wrap_content"
272272
android:layout_height="wrap_content"
273-
android:text="@string/label_total_traffic_download"
273+
android:text="@string/label_total_traffic_down"
274274
android:textAppearance="?attr/textAppearanceBodySmall"
275275
android:textColor="?attr/colorOnSurfaceVariant" />
276276
</LinearLayout>

V2rayNG/app/src/main/res/values-in/strings.xml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,13 @@ Nama Paket — cuma bisa kalo kamu pake Xray TUN, routeOnly aktif, dan Android 1
659659
<string name="pref_show_weather_chip_title">Tampilin info cuaca</string>
660660
<string name="pref_show_weather_chip_summary">Tampilin suhu saat ini di sebelah bar pencarian berdasarkan lokasi kamu. Nggak bisa aktif barengan sama chip total traffic</string>
661661
<string name="pref_show_total_traffic_chip_title">Tampilin chip total pemakaian traffic</string>
662-
<string name="pref_show_total_traffic_chip_summary">Tampilin total traffic upload + download dari semua profil di sebelah bar pencarian. Nggak bisa aktif barengan sama chip info cuaca</string>
662+
<string name="pref_show_total_traffic_chip_summary">Tampilin total traffic upload + download yang terus kehitung di sebelah bar pencarian. Nggak bisa aktif barengan sama chip info cuaca</string>
663+
<string name="pref_action_clear_total_traffic_title">Hapus data traffic chip</string>
664+
<string name="pref_action_clear_total_traffic_summary_empty">Belum ada data traffic chip yang tercatat</string>
665+
<string name="pref_action_clear_total_traffic_summary_set">Sekarang: %1$s</string>
666+
<string name="summary_pref_action_clear_total_traffic_disabled">Aktifin \"%1$s\" dulu biar traffic-nya mulai kecatat di sini</string>
667+
<string name="confirm_clear_total_traffic">Hapus data traffic chip beserta riwayat harian/bulanannya?</string>
668+
<string name="toast_total_traffic_cleared">Data traffic chip udah dihapus</string>
663669
<string name="pref_search_chip_gradient_title">Background chip gradasi</string>
664670
<string name="pref_search_chip_gradient_summary">Terapin background gradasi (warna primary ke tertiary) di chip bar pencarian pas chip cuaca atau chip total pemakaian lagi aktif</string>
665671

@@ -771,9 +777,11 @@ Nama Paket — cuma bisa kalo kamu pake Xray TUN, routeOnly aktif, dan Android 1
771777
<string name="confirm_reset_traffic_all">Reset penggunaan data buat semua grup? Nggak bisa dibatalin lho ya</string>
772778
<string name="pref_traffic_enabled_title">Tampilin Penggunaan Data</string>
773779
<string name="pref_traffic_enabled_summary">Tampilin jumlah upload dan download di tiap server</string>
774-
<string name="title_total_traffic_detail">Total Penggunaan Traffic</string>
780+
<string name="title_total_traffic_detail">Penggunaan Traffic Chip</string>
775781
<string name="label_total_traffic_upload">Upload</string>
776782
<string name="label_total_traffic_download">Download</string>
783+
<string name="label_total_traffic_up">Up</string>
784+
<string name="label_total_traffic_down">Down</string>
777785
<string name="label_total_traffic_combined">Gabungan</string>
778786
<string name="label_total_traffic_today">Hari Ini</string>
779787
<string name="label_total_traffic_month">Bulan Ini</string>

V2rayNG/app/src/main/res/values-ru/strings.xml

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -667,8 +667,14 @@
667667
<string name="title_search_bar_chip">Плашка строки поиска</string>
668668
<string name="pref_show_weather_chip_title">Показывать плашку погоды</string>
669669
<string name="pref_show_weather_chip_summary">Показывать текущую температуру рядом с поисковой строкой на основе вашего местоположения. Не может быть активна одновременно с плашкой общего трафика</string>
670-
<string name="pref_show_total_traffic_chip_title">Показывать плашку общего объема трафика</string>
671-
<string name="pref_show_total_traffic_chip_summary">Показывать общий трафик (отправка + загрузка) для всех профилей рядом со строкой поиска. Не может работать одновременно с плашкой погоды</string>
670+
<string name="pref_show_total_traffic_chip_title">Показывать плашку общего использования трафика</string>
671+
<string name="pref_show_total_traffic_chip_summary">Показывать суммарный исходящий и входящий трафик рядом с поисковой строкой. Не может быть активна одновременно с плашкой погоды</string>
672+
<string name="pref_action_clear_total_traffic_title">Очистить данные плашки трафика</string>
673+
<string name="pref_action_clear_total_traffic_summary_empty">Данные плашки трафика еще не записаны</string>
674+
<string name="pref_action_clear_total_traffic_summary_set">Текущие: %1$s</string>
675+
<string name="summary_pref_action_clear_total_traffic_disabled">Сначала включите \"%1$s\", чтобы здесь начала вестись запись трафика</string>
676+
<string name="confirm_clear_total_traffic">Очистить данные плашки трафика вместе с дневной/месячной историей?</string>
677+
<string name="toast_total_traffic_cleared">Данные плашки трафика очищены</string>
672678
<string name="pref_search_chip_gradient_title">Градиентный фон плашки</string>
673679
<string name="pref_search_chip_gradient_summary">Применить градиентный фон (от цвета primary к tertiary) на плашке строки поиска, когда активна плашка погоды или общего трафика</string>
674680

@@ -781,9 +787,11 @@
781787
<string name="confirm_reset_traffic_all">Сбросить статистику трафика для всех групп? Это действие нельзя отменить</string>
782788
<string name="pref_traffic_enabled_title">Показывать статистику трафика</string>
783789
<string name="pref_traffic_enabled_summary">Показывать объем загрузки и отдачи на каждом сервере</string>
784-
<string name="title_total_traffic_detail">Общий объем трафика</string>
790+
<string name="title_total_traffic_detail">Трафик плашки</string>
785791
<string name="label_total_traffic_upload">Отдача</string>
786792
<string name="label_total_traffic_download">Загрузка</string>
793+
<string name="label_total_traffic_up">Исх</string>
794+
<string name="label_total_traffic_down">Вх</string>
787795
<string name="label_total_traffic_combined">Всего</string>
788796
<string name="label_total_traffic_today">Сегодня</string>
789797
<string name="label_total_traffic_month">В этом месяце</string>

0 commit comments

Comments
 (0)