Skip to content

Commit 442227b

Browse files
authored
Merge pull request #16947 from wordpress-mobile/issue/16491-fix-percent-sign-localized
Fix percent sign should be localized
2 parents ec65f78 + cfe9a4e commit 442227b

File tree

54 files changed

+230
-231
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+230
-231
lines changed

WordPress/src/main/java/org/wordpress/android/ui/jetpack/backup/download/BackupDownloadViewModel.kt

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ import org.wordpress.android.ui.jetpack.common.providers.JetpackAvailableItemsPr
5858
import org.wordpress.android.ui.jetpack.usecases.GetActivityLogItemUseCase
5959
import org.wordpress.android.ui.pages.SnackbarMessageHolder
6060
import org.wordpress.android.ui.utils.UiString.UiStringRes
61-
import org.wordpress.android.ui.utils.UiString.UiStringResWithParams
6261
import org.wordpress.android.ui.utils.UiString.UiStringText
62+
import org.wordpress.android.util.text.PercentFormatter
6363
import org.wordpress.android.util.wizard.WizardManager
6464
import org.wordpress.android.util.wizard.WizardNavigationTarget
6565
import org.wordpress.android.util.wizard.WizardState
@@ -98,7 +98,8 @@ class BackupDownloadViewModel @Inject constructor(
9898
private val stateListItemBuilder: BackupDownloadStateListItemBuilder,
9999
private val postBackupDownloadUseCase: PostBackupDownloadUseCase,
100100
private val getBackupDownloadStatusUseCase: GetBackupDownloadStatusUseCase,
101-
@Named(UI_THREAD) private val mainDispatcher: CoroutineDispatcher
101+
@Named(UI_THREAD) private val mainDispatcher: CoroutineDispatcher,
102+
private val percentFormatter: PercentFormatter
102103
) : ScopedViewModel(mainDispatcher) {
103104
private var isStarted = false
104105
private lateinit var site: SiteModel
@@ -348,10 +349,7 @@ class BackupDownloadViewModel @Inject constructor(
348349
contentState as JetpackListItemState.ProgressState
349350
contentState.copy(
350351
progress = state.progress ?: 0,
351-
progressLabel = UiStringResWithParams(
352-
string.backup_download_progress_label,
353-
listOf(UiStringText(state.progress?.toString() ?: "0"))
354-
)
352+
progressLabel = UiStringText(percentFormatter.format(state.progress ?: 0))
355353
)
356354
} else {
357355
contentState

WordPress/src/main/java/org/wordpress/android/ui/jetpack/backup/download/builders/BackupDownloadStateListItemBuilder.kt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,14 @@ import org.wordpress.android.ui.utils.UiString.UiStringResWithParams
2828
import org.wordpress.android.ui.utils.UiString.UiStringText
2929
import org.wordpress.android.util.extensions.toFormattedDateString
3030
import org.wordpress.android.util.extensions.toFormattedTimeString
31+
import org.wordpress.android.util.text.PercentFormatter
3132
import java.util.Date
3233
import javax.inject.Inject
3334

3435
@Reusable
3536
class BackupDownloadStateListItemBuilder @Inject constructor(
36-
private val checkboxSpannableLabel: CheckboxSpannableLabel
37+
private val checkboxSpannableLabel: CheckboxSpannableLabel,
38+
private val percentFormatter: PercentFormatter
3739
) {
3840
fun buildDetailsListStateItems(
3941
published: Date,
@@ -242,10 +244,7 @@ class BackupDownloadStateListItemBuilder @Inject constructor(
242244

243245
private fun buildProgressState(progress: Int) = ProgressState(
244246
progress = progress,
245-
progressLabel = UiStringResWithParams(
246-
R.string.backup_download_progress_label,
247-
listOf(UiStringText(progress.toString()))
248-
)
247+
progressLabel = UiStringText(percentFormatter.format(progress))
249248
)
250249

251250
private fun buildBulletState(

WordPress/src/main/java/org/wordpress/android/ui/jetpack/restore/RestoreViewModel.kt

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ import org.wordpress.android.ui.jetpack.restore.usecases.PostRestoreUseCase
6161
import org.wordpress.android.ui.jetpack.usecases.GetActivityLogItemUseCase
6262
import org.wordpress.android.ui.pages.SnackbarMessageHolder
6363
import org.wordpress.android.ui.utils.UiString.UiStringRes
64-
import org.wordpress.android.ui.utils.UiString.UiStringResWithParams
6564
import org.wordpress.android.ui.utils.UiString.UiStringText
65+
import org.wordpress.android.util.text.PercentFormatter
6666
import org.wordpress.android.util.wizard.WizardManager
6767
import org.wordpress.android.util.wizard.WizardNavigationTarget
6868
import org.wordpress.android.util.wizard.WizardState
@@ -102,7 +102,8 @@ class RestoreViewModel @Inject constructor(
102102
private val stateListItemBuilder: RestoreStateListItemBuilder,
103103
private val postRestoreUseCase: PostRestoreUseCase,
104104
private val getRestoreStatusUseCase: GetRestoreStatusUseCase,
105-
@Named(UI_THREAD) private val mainDispatcher: CoroutineDispatcher
105+
@Named(UI_THREAD) private val mainDispatcher: CoroutineDispatcher,
106+
private val percentFormatter: PercentFormatter
106107
) : ScopedViewModel(mainDispatcher) {
107108
private var isStarted = false
108109
private lateinit var site: SiteModel
@@ -415,10 +416,7 @@ class RestoreViewModel @Inject constructor(
415416
contentState as JetpackListItemState.ProgressState
416417
contentState.copy(
417418
progress = restoreStatus.progress ?: 0,
418-
progressLabel = UiStringResWithParams(
419-
R.string.restore_progress_label,
420-
listOf(UiStringText(restoreStatus.progress?.toString() ?: "0"))
421-
),
419+
progressLabel = UiStringText(percentFormatter.format(restoreStatus.progress ?: 0)),
422420
progressInfoLabel = if (restoreStatus.currentEntry != null) {
423421
UiStringText("${restoreStatus.currentEntry}")
424422
} else {

WordPress/src/main/java/org/wordpress/android/ui/jetpack/restore/builders/RestoreStateListItemBuilder.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,15 @@ import org.wordpress.android.ui.utils.UiString.UiStringResWithParams
3030
import org.wordpress.android.ui.utils.UiString.UiStringText
3131
import org.wordpress.android.util.extensions.toFormattedDateString
3232
import org.wordpress.android.util.extensions.toFormattedTimeString
33+
import org.wordpress.android.util.text.PercentFormatter
3334
import java.util.Date
3435
import javax.inject.Inject
3536

3637
@Reusable
3738
class RestoreStateListItemBuilder @Inject constructor(
3839
private val checkboxSpannableLabel: CheckboxSpannableLabel,
39-
private val htmlMessageUtils: HtmlMessageUtils
40+
private val htmlMessageUtils: HtmlMessageUtils,
41+
private val percentFormatter: PercentFormatter
4042
) {
4143
@Suppress("LongParameterList")
4244
fun buildDetailsListStateItems(
@@ -296,9 +298,7 @@ class RestoreStateListItemBuilder @Inject constructor(
296298
private fun buildProgressState(progress: Int, isIndeterminate: Boolean = false) = ProgressState(
297299
progress = progress,
298300
isIndeterminate = isIndeterminate,
299-
progressLabel = UiStringResWithParams(
300-
R.string.restore_progress_label, listOf(UiStringText(progress.toString()))
301-
)
301+
progressLabel = UiStringText(percentFormatter.format(progress))
302302
)
303303

304304
private fun buildBulletState(

WordPress/src/main/java/org/wordpress/android/ui/jetpack/scan/builders/ScanStateListItemsBuilder.kt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import org.wordpress.android.ui.utils.HtmlMessageUtils
2626
import org.wordpress.android.ui.utils.UiString.UiStringRes
2727
import org.wordpress.android.ui.utils.UiString.UiStringResWithParams
2828
import org.wordpress.android.ui.utils.UiString.UiStringText
29+
import org.wordpress.android.util.text.PercentFormatter
2930
import org.wordpress.android.viewmodel.ResourceProvider
3031
import javax.inject.Inject
3132

@@ -36,7 +37,8 @@ class ScanStateListItemsBuilder @Inject constructor(
3637
private val resourceProvider: ResourceProvider,
3738
private val threatItemBuilder: ThreatItemBuilder,
3839
private val threatDetailsListItemsBuilder: ThreatDetailsListItemsBuilder,
39-
private val scanStore: ScanStore
40+
private val scanStore: ScanStore,
41+
private val percentFormatter: PercentFormatter
4042
) {
4143
@Suppress("LongParameterList")
4244
suspend fun buildScanStateListItems(
@@ -199,10 +201,7 @@ class ScanStateListItemsBuilder @Inject constructor(
199201
val scanDescription = DescriptionState(UiStringRes(descriptionRes))
200202
val scanProgress = ProgressState(
201203
progress = progress,
202-
progressLabel = UiStringResWithParams(
203-
R.string.scan_progress_label,
204-
listOf(UiStringText(progress.toString()))
205-
)
204+
progressLabel = UiStringText(percentFormatter.format(progress))
206205
)
207206

208207
items.add(scanIcon)

WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/detail/PostDayViewsMapper.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,16 @@ import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.Value
1111
import org.wordpress.android.ui.stats.refresh.utils.HUNDRED_THOUSAND
1212
import org.wordpress.android.ui.stats.refresh.utils.StatsDateFormatter
1313
import org.wordpress.android.ui.stats.refresh.utils.StatsUtils
14+
import org.wordpress.android.util.text.PercentFormatter
1415
import org.wordpress.android.viewmodel.ResourceProvider
1516
import javax.inject.Inject
1617

1718
class PostDayViewsMapper
1819
@Inject constructor(
1920
private val resourceProvider: ResourceProvider,
2021
private val statsUtils: StatsUtils,
21-
private val statsDateFormatter: StatsDateFormatter
22+
private val statsDateFormatter: StatsDateFormatter,
23+
private val percentFormatter: PercentFormatter
2224
) {
2325
fun buildTitle(
2426
selectedItem: Day,
@@ -63,7 +65,10 @@ class PostDayViewsMapper
6365
val percentage = when (previousValue) {
6466
value -> "0"
6567
0 -> ""
66-
else -> mapIntToString((difference * 100 / previousValue), isFormattedNumber)
68+
else -> {
69+
val percentageValue = difference.toFloat() / previousValue
70+
percentFormatter.format(percentageValue)
71+
}
6772
}
6873
val formattedDifference = mapIntToString(difference, isFormattedNumber)
6974
if (positive) {

WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/insights/usecases/MostPopularInsightsUseCase.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import org.wordpress.android.ui.stats.refresh.utils.ActionCardHandler
2222
import org.wordpress.android.ui.stats.refresh.utils.DateUtils
2323
import org.wordpress.android.ui.stats.refresh.utils.ItemPopupMenuHandler
2424
import org.wordpress.android.ui.stats.refresh.utils.StatsSiteProvider
25+
import org.wordpress.android.util.text.PercentFormatter
2526
import org.wordpress.android.viewmodel.ResourceProvider
2627
import javax.inject.Inject
2728
import javax.inject.Named
@@ -37,7 +38,8 @@ class MostPopularInsightsUseCase
3738
private val dateUtils: DateUtils,
3839
private val resourceProvider: ResourceProvider,
3940
private val popupMenuHandler: ItemPopupMenuHandler,
40-
private val actionCardHandler: ActionCardHandler
41+
private val actionCardHandler: ActionCardHandler,
42+
private val percentFormatter: PercentFormatter
4143
) : StatelessUseCase<InsightsMostPopularModel>(MOST_POPULAR_DAY_AND_HOUR, mainDispatcher, backgroundDispatcher) {
4244
override suspend fun loadCachedData(): InsightsMostPopularModel? {
4345
return mostPopularStore.getMostPopularInsights(statsSiteProvider.siteModel)
@@ -73,11 +75,11 @@ class MostPopularInsightsUseCase
7375
} else {
7476
val highestDayPercent = resourceProvider.getString(
7577
R.string.stats_most_popular_percent_views,
76-
domainModel.highestDayPercent.roundToInt()
78+
percentFormatter.format(domainModel.highestDayPercent.roundToInt())
7779
)
7880
val highestHourPercent = resourceProvider.getString(
7981
R.string.stats_most_popular_percent_views,
80-
domainModel.highestHourPercent.roundToInt()
82+
percentFormatter.format(domainModel.highestHourPercent.roundToInt())
8183
)
8284
items.add(
8385
QuickScanItem(

WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/utils/StatsUtils.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import org.wordpress.android.R
55
import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.BarChartItem.Bar
66
import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.LineChartItem.Line
77
import org.wordpress.android.util.LocaleManagerWrapper
8+
import org.wordpress.android.util.text.PercentFormatter
89
import org.wordpress.android.viewmodel.ResourceProvider
910
import java.text.DecimalFormat
1011
import java.util.TreeMap
@@ -19,7 +20,8 @@ const val MILLION = 1000000
1920
class StatsUtils
2021
@Inject constructor(
2122
private val resourceProvider: ResourceProvider,
22-
private val localeManager: LocaleManagerWrapper
23+
private val localeManager: LocaleManagerWrapper,
24+
private val percentFormatter: PercentFormatter
2325
) {
2426
private val suffixes = TreeMap(
2527
mapOf(
@@ -194,7 +196,10 @@ class StatsUtils
194196
val percentage = when (previousValue) {
195197
value -> "0"
196198
0L -> ""
197-
else -> mapLongToString((difference * 100 / previousValue), isFormattedNumber)
199+
else -> {
200+
val percentageValue = difference.toFloat() / previousValue
201+
percentFormatter.format(percentageValue)
202+
}
198203
}
199204
val formattedDifference = mapLongToString(difference, isFormattedNumber)
200205
if (positive) {
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package org.wordpress.android.util.text
2+
3+
import android.icu.text.NumberFormat
4+
import org.wordpress.android.util.LocaleManagerWrapper
5+
import java.math.RoundingMode
6+
import javax.inject.Inject
7+
8+
private const val MAXIMUM_FRACTION_DIGITS = 0
9+
private const val FORMAT_DIVISOR = 100
10+
11+
/**
12+
* Used to format a string with a percent sign (%) based on the locale.
13+
* @param localeManagerWrapper provides the Locale used to return the localized formatted string
14+
*/
15+
class PercentFormatter @Inject constructor(
16+
private val localeManagerWrapper: LocaleManagerWrapper
17+
) {
18+
/**
19+
* Returns a String with a percent sign (%) using the given Float parameter. The returned String uses the
20+
* default Locale.
21+
* @param value the value to be returned formatted
22+
* @return the formatted string
23+
*/
24+
fun format(
25+
value: Float,
26+
maxFractionDigits: Int = MAXIMUM_FRACTION_DIGITS,
27+
rounding: RoundingMode = RoundingMode.DOWN
28+
): String {
29+
val percentFormatter = NumberFormat.getPercentInstance(localeManagerWrapper.getLocale()).apply {
30+
maximumFractionDigits = maxFractionDigits
31+
roundingMode = rounding.ordinal
32+
}
33+
return percentFormatter.format(value)
34+
}
35+
36+
/**
37+
* Returns a String with a percent sign (%) using the given Int parameter. The Int value will be returned as the
38+
* percentage (e.g. if the Int value is 10, the returned String for Locale.US will be "10%"). The returned String
39+
* uses the default Locale.
40+
* @param value the value to be returned formatted
41+
* @return the formatted string
42+
*/
43+
fun format(
44+
value: Int,
45+
maxFractionDigits: Int = MAXIMUM_FRACTION_DIGITS,
46+
rounding: RoundingMode = RoundingMode.DOWN
47+
) = format(
48+
value = value.toFloat() / FORMAT_DIVISOR,
49+
maxFractionDigits,
50+
rounding
51+
)
52+
}

WordPress/src/main/res/values-ar/strings.xml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -731,7 +731,6 @@ Language: ar
731731
<string name="restore_complete_failed_icon_content_description">أيقونة الخطأ</string>
732732
<string name="restore_complete_failed_action_button_content_description">زر الانتهاء</string>
733733
<string name="restore_another_process_running">هناك عملية استعادة أخرى قيد التشغيل.</string>
734-
<string name="restore_progress_label">%1$s%%</string>
735734
<string name="restore_complete_visit_site_action_button">زيارة الموقع</string>
736735
<string name="restore_complete_icon_content_description">أيقونة الاستعادة</string>
737736
<string name="restore_complete_done_button_content_description">زر الانتهاء</string>
@@ -809,7 +808,6 @@ Language: ar
809808
<string name="backup_download_complete_download_action_button_content_description">زر التنزيل</string>
810809
<string name="backup_download_complete_description_with_two_parameters">أنشأنا نسخة احتياطية من موقعك بنجاح من %1$s %2$s.</string>
811810
<string name="backup_download_complete_icon_content_description">أيقونة جاهزية النسخ الاحتياطية القابلة للتنزيل</string>
812-
<string name="backup_download_progress_label">%1$s%%</string>
813811
<string name="backup_download_complete_page_title">نسختك الاحتياطية</string>
814812
<string name="backup_download_progress_header">إنشاء نسخة احتياطية قابلة للتنزيل من موقعك في الوقت الحالي</string>
815813
<string name="backup_download_progress_icon_content_description">جاري إنشاء أيقونة نسخة احتياطية قابلة للتنزيل</string>
@@ -1776,10 +1774,7 @@ Language: ar
17761774
<string name="notification_channel_reminder_title">تذكير</string>
17771775
<string name="stats_select_next_period_description">تحديد الفترة التالية</string>
17781776
<string name="stats_select_previous_period_description">تحديد الفترة السابقة</string>
1779-
<string name="stats_most_popular_percent_views">%1$d%% من المشاهدات</string>
17801777
<string name="stats_insights_popular">الوقت الأكثر شعبية</string>
1781-
<string name="stats_traffic_change">%1$s (%2$s%%)</string>
1782-
<string name="stats_traffic_increase">+%1$s (%2$s%%)</string>
17831778
<string name="new_site_creation_site_preview_content_description">عرض معاينة الموقع</string>
17841779
<string name="new_site_creation_clear_all_content_description">مسح</string>
17851780
<string name="site_created_but_not_fetched_snackbar_message">يبدو أنَّ الاتصال بطيء لديك. إذا كنت لا ترى موقعك الجديد في القائمة، فحاول التحديث مجددًا.</string>

0 commit comments

Comments
 (0)