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

Verified Commit 42e1fff9 authored by Fahim M. Choudhury's avatar Fahim M. Choudhury
Browse files

refactor: add locale-aware formatting for user rating

parent e2328ff8
Loading
Loading
Loading
Loading
Loading
+7 −5
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ import foundation.e.apps.ui.compose.state.InstallButtonAction
import foundation.e.apps.ui.compose.state.InstallButtonState
import foundation.e.apps.ui.compose.theme.AppTheme
import foundation.e.apps.ui.search.v2.SearchTabType
import foundation.e.apps.ui.utils.AppUserRatingFormatter

@RunWith(AndroidJUnit4::class)
class SearchResultsContentTest {
@@ -136,8 +137,9 @@ class SearchResultsContentTest {
    fun applicationMapping_setsAuthorRatingAndPrimaryAction() {
        val notAvailable = composeRule.activity.getString(R.string.not_available)
        val openLabel = composeRule.activity.getString(R.string.open)
        val expectedRating = "4"
        val hiddenRating = "4.9"
        val locale = composeRule.activity.resources.configuration.locales[0]
        val expectedRating = AppUserRatingFormatter.format(4.4, locale)
        val hiddenRating = AppUserRatingFormatter.format(4.9, locale)

        renderSearchResults(
            tabs = listOf(SearchTabType.OPEN_SOURCE),
@@ -149,7 +151,7 @@ class SearchResultsContentTest {
                        author = "",
                        package_name = "com.example.rated",
                        source = Source.PLAY_STORE,
                        ratings = Ratings(usageQualityScore = 4.0),
                        ratings = Ratings(usageQualityScore = 4.4),
                        status = Status.INSTALLED,
                    ),
                    Application(
@@ -180,10 +182,10 @@ class SearchResultsContentTest {
        )

        composeRule.onNodeWithText("com.example.rated").assertIsDisplayed()
        composeRule.onNodeWithText(expectedRating).assertIsDisplayed()
        composeRule.onNodeWithText(expectedRating ?: "").assertIsDisplayed()
        composeRule.onNodeWithText(openLabel).assertIsDisplayed()
        composeRule.onNodeWithText(notAvailable).assertIsDisplayed()
        composeRule.onAllNodesWithText(hiddenRating).assertCountEquals(0)
        composeRule.onAllNodesWithText(hiddenRating ?: "").assertCountEquals(0)
    }

    @Test
+4 −5
Original line number Diff line number Diff line
@@ -358,13 +358,14 @@ class ApplicationFragment : TimeoutFragment(R.layout.fragment_application) {

    private fun updateAppRating(it: Application) {
        binding.ratingsInclude.apply {
            val formattedRating = AppUserRatingFormatter.format(it.ratings.usageQualityScore)
            val locale = resources.configuration.locales[0]
            val formattedRating = AppUserRatingFormatter.format(it.ratings.usageQualityScore, locale)
            if (formattedRating != null) {
                appRating.text = getString(R.string.rating_out_of, formattedRating)
                appRating.setCompoundDrawablesWithIntrinsicBounds(
                    ContextCompat.getDrawable(requireContext(), R.drawable.ic_star_blank),
                    null,
                    getRatingDrawable(formattedRating),
                    getRatingDrawable(it.ratings.usageQualityScore),
                    null
                )
                appRating.compoundDrawablePadding = DRAWABLE_PADDING
@@ -1076,9 +1077,7 @@ class ApplicationFragment : TimeoutFragment(R.layout.fragment_application) {
        return applyDotAccent(dotColor)
    }

    private fun getRatingDrawable(reviewRating: String): Drawable? {
        val rating = reviewRating.toDouble()

    private fun getRatingDrawable(rating: Double): Drawable? {
        var dotColor = ContextCompat.getColor(requireContext(), R.color.colorGreen)
        if (rating <= LOW_REVIEW_THRESHOLD) {
            dotColor = ContextCompat.getColor(requireContext(), R.color.colorRed)
+2 −1
Original line number Diff line number Diff line
@@ -212,7 +212,8 @@ class ApplicationListRVAdapter(
            appRating.isVisible = false
            return
        }
        val formattedRating = AppUserRatingFormatter.format(searchApp.ratings.usageQualityScore)
        val locale = root.context.resources.configuration.locales[0]
        val formattedRating = AppUserRatingFormatter.format(searchApp.ratings.usageQualityScore, locale)
        appRating.text = formattedRating ?: root.context.getString(R.string.not_available)
    }

+3 −1
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
@@ -553,9 +554,10 @@ private fun Application.toSearchResultUiState(buttonState: InstallButtonState):
        )
    }

    val locale = LocalConfiguration.current.locales[0]
    val ratingText = when {
        source == Source.OPEN_SOURCE || source == Source.PWA || isSystemApp -> ""
        else -> AppUserRatingFormatter.format(ratings.usageQualityScore)
        else -> AppUserRatingFormatter.format(ratings.usageQualityScore, locale)
            ?: stringResource(R.string.not_available)
    }

+9 −6
Original line number Diff line number Diff line
@@ -17,19 +17,22 @@

package foundation.e.apps.ui.utils

import java.text.NumberFormat
import java.util.Locale

object AppUserRatingFormatter {

    private const val MIN_VALID_RATING = 0.1

    fun format(rating: Double?): String? {
    fun format(rating: Double?, locale: Locale): String? {
        if (rating == null || rating < MIN_VALID_RATING) {
            return null
        }

        return if (rating % 1 == 0.0) {
            rating.toInt().toString()
        } else {
            rating.toString()
        }
        return NumberFormat.getNumberInstance(locale).apply {
            minimumFractionDigits = 0
            maximumFractionDigits = 1
            isGroupingUsed = false
        }.format(rating)
    }
}
Loading