Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b93a209b authored by Guillaume Jacquart's avatar Guillaume Jacquart
Browse files

1964: add tousand separators on leaks counts.

parent 9c780650
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 MURENA SAS
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
package foundation.e.advancedprivacy.common

import android.content.Context
import android.icu.number.NumberFormatter

class BigNumberFormatter(context: Context) {
    private val formatter = NumberFormatter.withLocale(context.resources.configuration.locales[0])

    fun format(number: Int): CharSequence = formatter.format(number)
}
+5 −2
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 MURENA SAS
 * Copyright (C) 2023-2024 MURENA SAS
 * Copyright (C) 2021 E FOUNDATION
 *
 * This program is free software: you can redistribute it and/or modify
@@ -29,6 +29,7 @@ import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.navigation.fragment.findNavController
import foundation.e.advancedprivacy.R
import foundation.e.advancedprivacy.common.BigNumberFormatter
import foundation.e.advancedprivacy.common.NavToolbarFragment
import foundation.e.advancedprivacy.databinding.FragmentDashboardBinding
import foundation.e.advancedprivacy.domain.entities.FeatureState
@@ -39,12 +40,14 @@ import org.koin.androidx.viewmodel.ext.android.viewModel

class DashboardFragment : NavToolbarFragment(R.layout.fragment_dashboard) {
    private val viewModel: DashboardViewModel by viewModel()
    private lateinit var numberFormatter: BigNumberFormatter

    private lateinit var binding: FragmentDashboardBinding

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding = FragmentDashboardBinding.bind(view)
        numberFormatter = BigNumberFormatter(requireContext())

        with(binding.dataBlockedTrackers) {
            primaryMessage.apply {
@@ -164,7 +167,7 @@ class DashboardFragment : NavToolbarFragment(R.layout.fragment_dashboard) {
    }

    private fun render(state: DashboardState) {
        binding.dataBlockedTrackers.number.text = state.blockedCallsCount.toString()
        binding.dataBlockedTrackers.number.text = numberFormatter.format(state.blockedCallsCount)
        binding.dataApps.number.text = state.appsWithCallsCount.toString()

        with(binding.trackersControl) {
+7 −3
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 MURENA SAS
 * Copyright (C) 2023-2024 MURENA SAS
 * Copyright (C) 2021 E FOUNDATION
 *
 * This program is free software: you can redistribute it and/or modify
@@ -33,6 +33,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.divider.MaterialDividerItemDecoration
import com.google.android.material.snackbar.Snackbar
import foundation.e.advancedprivacy.R
import foundation.e.advancedprivacy.common.BigNumberFormatter
import foundation.e.advancedprivacy.common.NavToolbarFragment
import foundation.e.advancedprivacy.databinding.ApptrackersFragmentBinding
import foundation.e.advancedprivacy.features.trackers.setupDisclaimerBlock
@@ -45,6 +46,8 @@ class AppTrackersFragment : NavToolbarFragment(R.layout.apptrackers_fragment) {
    private val args: AppTrackersFragmentArgs by navArgs()
    private val viewModel: AppTrackersViewModel by viewModel { parametersOf(args.appUid) }

    private lateinit var numberFormatter: BigNumberFormatter

    private lateinit var binding: ApptrackersFragmentBinding

    override fun getTitle(): CharSequence {
@@ -59,6 +62,7 @@ class AppTrackersFragment : NavToolbarFragment(R.layout.apptrackers_fragment) {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding = ApptrackersFragmentBinding.bind(view)
        numberFormatter = BigNumberFormatter(requireContext())

        binding.blockAllToggle.setOnClickListener {
            viewModel.onToggleBlockAll(binding.blockAllToggle.isChecked)
@@ -145,8 +149,8 @@ class AppTrackersFragment : NavToolbarFragment(R.layout.apptrackers_fragment) {

        binding.dataBlockedLeaks.apply {
            primaryMessage.setText(R.string.apptrackers_blocked_leaks_primary)
            number.text = state.blocked.toString()
            secondaryMessage.text = getString(R.string.apptrackers_blocked_leaks_secondary, state.leaked.toString())
            number.text = numberFormatter.format(state.blocked)
            secondaryMessage.text = getString(R.string.apptrackers_blocked_leaks_secondary, numberFormatter.format(state.leaked))
        }

        binding.blockAllToggle.isChecked = state.isBlockingActivated
+6 −3
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 MURENA SAS
 * Copyright (C) 2023-2024 MURENA SAS
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
@@ -31,6 +31,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.divider.MaterialDividerItemDecoration
import com.google.android.material.snackbar.Snackbar
import foundation.e.advancedprivacy.R
import foundation.e.advancedprivacy.common.BigNumberFormatter
import foundation.e.advancedprivacy.common.NavToolbarFragment
import foundation.e.advancedprivacy.databinding.TrackerdetailsFragmentBinding
import foundation.e.advancedprivacy.features.trackers.setupDisclaimerBlock
@@ -42,6 +43,7 @@ class TrackerDetailsFragment : NavToolbarFragment(R.layout.trackerdetails_fragme

    private val args: TrackerDetailsFragmentArgs by navArgs()
    private val viewModel: TrackerDetailsViewModel by viewModel { parametersOf(args.trackerId) }
    private lateinit var numberFormatter: BigNumberFormatter

    private lateinit var binding: TrackerdetailsFragmentBinding

@@ -57,6 +59,7 @@ class TrackerDetailsFragment : NavToolbarFragment(R.layout.trackerdetails_fragme
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding = TrackerdetailsFragmentBinding.bind(view)
        numberFormatter = BigNumberFormatter(requireContext())

        binding.blockAllToggle.setOnClickListener {
            viewModel.onToggleBlockAll(binding.blockAllToggle.isChecked)
@@ -136,8 +139,8 @@ class TrackerDetailsFragment : NavToolbarFragment(R.layout.trackerdetails_fragme

        binding.dataBlockedLeaks.apply {
            primaryMessage.setText(R.string.trackerdetails_blocked_leaks_primary)
            number.text = state.blockedCount.toString()
            secondaryMessage.text = getString(R.string.trackerdetails_blocked_leaks_secondary, state.leakedCount.toString())
            number.text = numberFormatter.format(state.blockedCount)
            secondaryMessage.text = getString(R.string.trackerdetails_blocked_leaks_secondary, numberFormatter.format(state.leakedCount))
        }

        binding.blockAllToggle.isChecked = state.isBlockAllActivated
+17 −5
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 MURENA SAS
 * Copyright (C) 2023-2024 MURENA SAS
 * Copyright (C) 2022 E FOUNDATION
 *
 * This program is free software: you can redistribute it and/or modify
@@ -34,6 +34,7 @@ import androidx.annotation.StringRes
import foundation.e.advancedprivacy.R
import foundation.e.advancedprivacy.Widget
import foundation.e.advancedprivacy.Widget.Companion.isDarkText
import foundation.e.advancedprivacy.common.BigNumberFormatter
import foundation.e.advancedprivacy.domain.entities.FeatureState
import foundation.e.advancedprivacy.domain.entities.TrackerMode
import foundation.e.advancedprivacy.main.MainActivity
@@ -60,6 +61,8 @@ fun renderAll(context: Context, state: State) {
}

fun render(context: Context, state: State, appWidgetManager: AppWidgetManager, widgetId: Int) {
    val numberFormatter = BigNumberFormatter(context)

    val views = buildLayout(context, appWidgetManager, widgetId)

    applyDarkText(context, isDarkText, views)
@@ -76,12 +79,22 @@ fun render(context: Context, state: State, appWidgetManager: AppWidgetManager, w

        setTextViewText(
            R.id.data_blocked_trackers_secondary,
            buildDataSecondarySpan(context, isDarkText, state.blockedCallsCount, R.string.widget_data_blocked_trackers_secondary)
            buildDataSecondarySpan(
                context,
                isDarkText,
                numberFormatter.format(state.blockedCallsCount).toString(),
                R.string.widget_data_blocked_trackers_secondary
            )
        )

        setTextViewText(
            R.id.data_apps_secondary,
            buildDataSecondarySpan(context, isDarkText, state.appsWithCallsCount, R.string.widget_data_apps_secondary)
            buildDataSecondarySpan(
                context,
                isDarkText,
                state.appsWithCallsCount.toString(),
                R.string.widget_data_apps_secondary
            )
        )

        val trackersEnabled = state.trackerMode != TrackerMode.VULNERABLE
@@ -198,7 +211,7 @@ private fun applyDarkText(context: Context, isDarkText: Boolean, views: RemoteVi
    }
}

private fun buildDataSecondarySpan(context: Context, isDarkText: Boolean, count: Int, @StringRes secondaryRes: Int): CharSequence {
private fun buildDataSecondarySpan(context: Context, isDarkText: Boolean, countStr: String, @StringRes secondaryRes: Int): CharSequence {
    val primaryColor = context.getColor(
        if (isDarkText) {
            R.color.on_surface_medium_emphasis_light
@@ -209,7 +222,6 @@ private fun buildDataSecondarySpan(context: Context, isDarkText: Boolean, count:

    val secondaryColor = context.getColor(if (isDarkText) R.color.on_surface_disabled_light else R.color.on_primary_medium_emphasis)

    val countStr = count.toString()
    val secondary = context.getString(secondaryRes)

    val spannable = SpannableString("$countStr $secondary")
Loading