diff --git a/tools/check/forbidden_strings_in_code.txt b/tools/check/forbidden_strings_in_code.txt index 7686cb0b7c..7e00295a48 100644 --- a/tools/check/forbidden_strings_in_code.txt +++ b/tools/check/forbidden_strings_in_code.txt @@ -149,4 +149,10 @@ android\.app\.AlertDialog new Gson\(\) ### Use matrixOneTimeWorkRequestBuilder -import androidx.work.OneTimeWorkRequestBuilder===1 \ No newline at end of file +import androidx.work.OneTimeWorkRequestBuilder===1 + +### Use TextUtils.formatFileSize +Formatter\.formatFileSize===1 + +### Use TextUtils.formatFileSize with short format param to true +Formatter\.formatShortFileSize===1 diff --git a/vector/src/main/java/im/vector/riotx/core/utils/TextUtils.kt b/vector/src/main/java/im/vector/riotx/core/utils/TextUtils.kt index 9d980e7f98..a7fa2cb350 100644 --- a/vector/src/main/java/im/vector/riotx/core/utils/TextUtils.kt +++ b/vector/src/main/java/im/vector/riotx/core/utils/TextUtils.kt @@ -16,6 +16,9 @@ package im.vector.riotx.core.utils +import android.content.Context +import android.os.Build +import android.text.format.Formatter import java.util.* object TextUtils { @@ -42,4 +45,28 @@ object TextUtils { return value.toString() } } + + /** + * Since Android O, the system considers that 1ko = 1000 bytes instead of 1024 bytes. We want to avoid that for the moment. + */ + fun formatFileSize(context: Context, sizeBytes: Long, useShortFormat: Boolean = false): String { + val normalizedSize = if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.N) { + sizeBytes + } else { + // First convert the size + when { + sizeBytes < 1024 -> sizeBytes + sizeBytes < 1024 * 1024 -> sizeBytes * 1000 / 1024 + sizeBytes < 1024 * 1024 * 1024 -> sizeBytes * 1000 / 1024 * 1000 / 1024 + else -> sizeBytes * 1000 / 1024 * 1000 / 1024 * 1000 / 1024 + } + } + + return if (useShortFormat) { + Formatter.formatShortFileSize(context, normalizedSize) + } else { + Formatter.formatFileSize(context, normalizedSize) + + } + } } \ No newline at end of file diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt index 7c7b90cd4b..ad9201c628 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt @@ -27,8 +27,6 @@ import android.os.Bundle import android.os.Parcelable import android.text.Editable import android.text.Spannable -import android.text.TextUtils -import android.text.format.Formatter import android.view.* import android.view.inputmethod.InputMethodManager import android.widget.TextView @@ -149,18 +147,15 @@ class RoomDetailFragment : * @param displayName the display name to sanitize * @return the sanitized display name */ - fun sanitizeDisplayname(displayName: String): String? { - // sanity checks - if (!TextUtils.isEmpty(displayName)) { - val ircPattern = " (IRC)" - - if (displayName.endsWith(ircPattern)) { - return displayName.substring(0, displayName.length - ircPattern.length) - } + private fun sanitizeDisplayName(displayName: String): String { + if (displayName.endsWith(ircPattern)) { + return displayName.substring(0, displayName.length - ircPattern.length) } return displayName } + + private const val ircPattern = " (IRC)" } private val roomDetailArgs: RoomDetailArgs by args() @@ -264,8 +259,8 @@ class RoomDetailFragment : .setTitle(R.string.dialog_title_error) .setMessage(getString(R.string.error_file_too_big, error.filename, - Formatter.formatFileSize(requireContext(), error.fileSizeInBytes), - Formatter.formatFileSize(requireContext(), error.homeServerLimitInBytes) + TextUtils.formatFileSize(requireContext(), error.fileSizeInBytes), + TextUtils.formatFileSize(requireContext(), error.homeServerLimitInBytes) )) .setPositiveButton(R.string.ok, null) .show() @@ -987,23 +982,23 @@ class RoomDetailFragment : // var vibrate = false val myDisplayName = session.getUser(session.myUserId)?.displayName - if (TextUtils.equals(myDisplayName, text)) { + if (myDisplayName == text) { // current user - if (TextUtils.isEmpty(composerLayout.composerEditText.text)) { + if (composerLayout.composerEditText.text.isBlank()) { composerLayout.composerEditText.append(Command.EMOTE.command + " ") composerLayout.composerEditText.setSelection(composerLayout.composerEditText.text.length) // vibrate = true } } else { // another user - if (TextUtils.isEmpty(composerLayout.composerEditText.text)) { + if (composerLayout.composerEditText.text.isBlank()) { // Ensure displayName will not be interpreted as a Slash command if (text.startsWith("/")) { composerLayout.composerEditText.append("\\") } - composerLayout.composerEditText.append(sanitizeDisplayname(text)!! + ": ") + composerLayout.composerEditText.append(sanitizeDisplayName(text) + ": ") } else { - composerLayout.composerEditText.text.insert(composerLayout.composerEditText.selectionStart, sanitizeDisplayname(text)!! + " ") + composerLayout.composerEditText.text.insert(composerLayout.composerEditText.selectionStart, sanitizeDisplayName(text) + " ") } // vibrate = true diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/helper/ContentUploadStateTrackerBinder.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/helper/ContentUploadStateTrackerBinder.kt index 09b2e86a83..96cb7f0d8e 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/helper/ContentUploadStateTrackerBinder.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/helper/ContentUploadStateTrackerBinder.kt @@ -16,7 +16,6 @@ package im.vector.riotx.features.home.room.detail.timeline.helper -import android.text.format.Formatter import android.view.View import android.view.ViewGroup import android.widget.ProgressBar @@ -28,6 +27,7 @@ import im.vector.riotx.R import im.vector.riotx.core.di.ActiveSessionHolder import im.vector.riotx.core.error.ErrorFormatter import im.vector.riotx.core.resources.ColorProvider +import im.vector.riotx.core.utils.TextUtils import im.vector.riotx.features.ui.getMessageTextColor import javax.inject.Inject @@ -126,8 +126,8 @@ private class ContentMediaProgressUpdater(private val progressLayout: ViewGroup, progressBar?.isIndeterminate = false progressBar?.progress = percent.toInt() progressTextView?.text = progressLayout.context.getString(resId, - Formatter.formatShortFileSize(progressLayout.context, current), - Formatter.formatShortFileSize(progressLayout.context, total)) + TextUtils.formatFileSize(progressLayout.context, current, true), + TextUtils.formatFileSize(progressLayout.context, total, true)) progressTextView?.setTextColor(colorProvider.getMessageTextColor(SendState.SENDING)) } diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsGeneralFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsGeneralFragment.kt index 2bec8cf103..e51feb2363 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsGeneralFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsGeneralFragment.kt @@ -20,7 +20,7 @@ import android.app.Activity import android.content.Context import android.content.Intent import android.text.Editable -import android.text.TextUtils +import android.util.Patterns import android.view.View import android.view.ViewGroup import android.view.inputmethod.InputMethodManager @@ -171,7 +171,7 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() { MXSession.getApplicationSizeCaches(activity, object : SimpleApiCallback() { override fun onSuccess(size: Long) { if (null != activity) { - it.summary = android.text.format.Formatter.formatFileSize(activity, size) + it.summary = TextUtils.formatFileSize(activity, size) } } }) @@ -189,7 +189,7 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() { val size = getSizeOfFiles(requireContext(), File(requireContext().cacheDir, DiskCache.Factory.DEFAULT_DISK_CACHE_DIR)) - it.summary = android.text.format.Formatter.formatFileSize(activity, size.toLong()) + it.summary = TextUtils.formatFileSize(requireContext(), size.toLong()) it.onPreferenceClickListener = Preference.OnPreferenceClickListener { GlobalScope.launch(Dispatchers.Main) { @@ -208,7 +208,7 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() { File(requireContext().cacheDir, DiskCache.Factory.DEFAULT_DISK_CACHE_DIR)) } - it.summary = android.text.format.Formatter.formatFileSize(activity, newSize.toLong()) + it.summary = TextUtils.formatFileSize(requireContext(), newSize.toLong()) hideLoadingView() } @@ -534,7 +534,7 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() { private fun addEmail(email: String) { // check first if the email syntax is valid // if email is null , then also its invalid email - if (TextUtils.isEmpty(email) || !android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()) { + if (email.isBlank() || !Patterns.EMAIL_ADDRESS.matcher(email).matches()) { activity?.toast(R.string.auth_invalid_email) return } @@ -719,9 +719,9 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() { val newPwd = newPasswordText.text.toString().trim() val newConfirmPwd = confirmNewPasswordText.text.toString().trim() - updateButton.isEnabled = oldPwd.isNotEmpty() && newPwd.isNotEmpty() && TextUtils.equals(newPwd, newConfirmPwd) + updateButton.isEnabled = oldPwd.isNotEmpty() && newPwd.isNotEmpty() && newPwd == newConfirmPwd - if (newPwd.isNotEmpty() && newConfirmPwd.isNotEmpty() && !TextUtils.equals(newPwd, newConfirmPwd)) { + if (newPwd.isNotEmpty() && newConfirmPwd.isNotEmpty() && newPwd != newConfirmPwd) { confirmNewPasswordTil.error = getString(R.string.passwords_do_not_match) } }