Consistently format byte sizes.

This commit is contained in:
Greyson Parrelli
2025-03-12 15:24:15 -04:00
parent d2006853c7
commit 22d908385b
16 changed files with 31 additions and 124 deletions

View File

@@ -262,7 +262,7 @@ sealed interface BackupStatusData {
class NotEnoughFreeSpace( class NotEnoughFreeSpace(
requiredSpace: ByteSize requiredSpace: ByteSize
) : BackupStatusData { ) : BackupStatusData {
val requiredSpace = requiredSpace.toUnitString(maxPlaces = 2) val requiredSpace = requiredSpace.toUnitString()
override val iconRes: Int = R.drawable.symbol_backup_error_24 override val iconRes: Int = R.drawable.symbol_backup_error_24
@@ -301,8 +301,8 @@ sealed interface BackupStatusData {
@Composable get() = when (restoreStatus) { @Composable get() = when (restoreStatus) {
RestoreStatus.NORMAL -> stringResource( RestoreStatus.NORMAL -> stringResource(
R.string.BackupStatus__status_size_of_size, R.string.BackupStatus__status_size_of_size,
bytesDownloaded.toUnitString(maxPlaces = 2), bytesDownloaded.toUnitString(),
bytesTotal.toUnitString(maxPlaces = 2) bytesTotal.toUnitString()
) )
RestoreStatus.LOW_BATTERY -> stringResource(R.string.BackupStatus__status_device_has_low_battery) RestoreStatus.LOW_BATTERY -> stringResource(R.string.BackupStatus__status_device_has_low_battery)

View File

@@ -20,6 +20,7 @@ import com.pnikosis.materialishprogress.ProgressWheel;
import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode; import org.greenrobot.eventbus.ThreadMode;
import org.signal.core.util.ByteSize;
import org.signal.core.util.logging.Log; import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.database.AttachmentTable; import org.thoughtcrime.securesms.database.AttachmentTable;
@@ -115,7 +116,7 @@ public class DocumentView extends FrameLayout {
this.fileName.setText(OptionalUtil.or(documentSlide.getFileName(), this.fileName.setText(OptionalUtil.or(documentSlide.getFileName(),
documentSlide.getCaption()) documentSlide.getCaption())
.orElse(getContext().getString(R.string.DocumentView_unnamed_file))); .orElse(getContext().getString(R.string.DocumentView_unnamed_file)));
this.fileSize.setText(Util.getPrettyFileSize(documentSlide.getFileSize())); this.fileSize.setText(new ByteSize(documentSlide.getFileSize()).toUnitString(2));
this.document.setText(documentSlide.getFileType(getContext()).orElse("").toLowerCase()); this.document.setText(documentSlide.getFileType(getContext()).orElse("").toLowerCase());
this.setOnClickListener(new OpenClickedListener(documentSlide)); this.setOnClickListener(new OpenClickedListener(documentSlide));
} }

View File

@@ -103,7 +103,6 @@ import org.thoughtcrime.securesms.keyvalue.protos.ArchiveUploadProgressState
import org.thoughtcrime.securesms.payments.FiatMoneyUtil import org.thoughtcrime.securesms.payments.FiatMoneyUtil
import org.thoughtcrime.securesms.util.DateUtils import org.thoughtcrime.securesms.util.DateUtils
import org.thoughtcrime.securesms.util.ServiceUtil import org.thoughtcrime.securesms.util.ServiceUtil
import org.thoughtcrime.securesms.util.Util
import org.thoughtcrime.securesms.util.navigation.safeNavigate import org.thoughtcrime.securesms.util.navigation.safeNavigate
import org.thoughtcrime.securesms.util.viewModel import org.thoughtcrime.securesms.util.viewModel
import java.math.BigDecimal import java.math.BigDecimal
@@ -610,7 +609,7 @@ private fun LazyListScope.appendBackupDetailsItems(
color = MaterialTheme.colorScheme.onSurface color = MaterialTheme.colorScheme.onSurface
) )
Text( Text(
text = Util.getPrettyFileSize(backupMediaSize), text = backupMediaSize.bytes.toUnitString(),
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant color = MaterialTheme.colorScheme.onSurfaceVariant
) )

View File

@@ -3,13 +3,13 @@ package org.thoughtcrime.securesms.components.settings.app.data
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.navigation.Navigation import androidx.navigation.Navigation
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import org.signal.core.util.bytes
import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.components.settings.DSLConfiguration import org.thoughtcrime.securesms.components.settings.DSLConfiguration
import org.thoughtcrime.securesms.components.settings.DSLSettingsFragment import org.thoughtcrime.securesms.components.settings.DSLSettingsFragment
import org.thoughtcrime.securesms.components.settings.DSLSettingsText import org.thoughtcrime.securesms.components.settings.DSLSettingsText
import org.thoughtcrime.securesms.components.settings.configure import org.thoughtcrime.securesms.components.settings.configure
import org.thoughtcrime.securesms.mms.SentMediaQuality import org.thoughtcrime.securesms.mms.SentMediaQuality
import org.thoughtcrime.securesms.util.Util
import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter
import org.thoughtcrime.securesms.util.navigation.safeNavigate import org.thoughtcrime.securesms.util.navigation.safeNavigate
import org.thoughtcrime.securesms.webrtc.CallDataMode import org.thoughtcrime.securesms.webrtc.CallDataMode
@@ -46,7 +46,7 @@ class DataAndStorageSettingsFragment : DSLSettingsFragment(R.string.preferences_
return configure { return configure {
clickPref( clickPref(
title = DSLSettingsText.from(R.string.preferences_data_and_storage__manage_storage), title = DSLSettingsText.from(R.string.preferences_data_and_storage__manage_storage),
summary = DSLSettingsText.from(Util.getPrettyFileSize(state.totalStorageUse)), summary = DSLSettingsText.from(state.totalStorageUse.bytes.toUnitString()),
onClick = { onClick = {
Navigation.findNavController(requireView()).safeNavigate(R.id.action_dataAndStorageSettingsFragment_to_storagePreferenceFragment) Navigation.findNavController(requireView()).safeNavigate(R.id.action_dataAndStorageSettingsFragment_to_storagePreferenceFragment)
} }

View File

@@ -61,6 +61,7 @@ import org.signal.core.ui.Scaffolds
import org.signal.core.ui.SignalPreview import org.signal.core.ui.SignalPreview
import org.signal.core.ui.Texts import org.signal.core.ui.Texts
import org.signal.core.ui.theme.SignalTheme import org.signal.core.ui.theme.SignalTheme
import org.signal.core.util.bytes
import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.billing.upgrade.UpgradeToEnableOptimizedStorageSheet import org.thoughtcrime.securesms.billing.upgrade.UpgradeToEnableOptimizedStorageSheet
import org.thoughtcrime.securesms.billing.upgrade.UpgradeToPaidTierBottomSheet import org.thoughtcrime.securesms.billing.upgrade.UpgradeToPaidTierBottomSheet
@@ -71,7 +72,6 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.mediaoverview.MediaOverviewActivity import org.thoughtcrime.securesms.mediaoverview.MediaOverviewActivity
import org.thoughtcrime.securesms.preferences.widgets.StorageGraphView import org.thoughtcrime.securesms.preferences.widgets.StorageGraphView
import org.thoughtcrime.securesms.util.BottomSheetUtil import org.thoughtcrime.securesms.util.BottomSheetUtil
import org.thoughtcrime.securesms.util.Util
import org.thoughtcrime.securesms.util.viewModel import org.thoughtcrime.securesms.util.viewModel
import java.text.NumberFormat import java.text.NumberFormat
@@ -360,7 +360,7 @@ private fun StorageOverview(
) )
it.findViewById<StorageGraphView>(R.id.storageGraphView).setStorageBreakdown(breakdownEntries) it.findViewById<StorageGraphView>(R.id.storageGraphView).setStorageBreakdown(breakdownEntries)
it.findViewById<TextView>(R.id.total_size).text = Util.getPrettyFileSize(breakdownEntries.totalSize) it.findViewById<TextView>(R.id.total_size).text = breakdownEntries.totalSize.bytes.toUnitString()
} }
it.findViewById<View>(R.id.free_up_space).setOnClickListener { it.findViewById<View>(R.id.free_up_space).setOnClickListener {

View File

@@ -35,6 +35,7 @@ import com.annimon.stream.Stream;
import com.bumptech.glide.RequestManager; import com.bumptech.glide.RequestManager;
import com.codewaves.stickyheadergrid.StickyHeaderGridAdapter; import com.codewaves.stickyheadergrid.StickyHeaderGridAdapter;
import org.signal.core.util.ByteSize;
import org.signal.libsignal.protocol.util.Pair; import org.signal.libsignal.protocol.util.Pair;
import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.attachments.AttachmentId; import org.thoughtcrime.securesms.attachments.AttachmentId;
@@ -339,7 +340,7 @@ final class MediaGalleryAllAdapter extends StickyHeaderGridAdapter {
super.bind(context, mediaRecord, slide); super.bind(context, mediaRecord, slide);
this.slide = slide; this.slide = slide;
if (showFileSizes | detailView) { if (showFileSizes | detailView) {
imageFileSize.setText(Util.getPrettyFileSize(slide.getFileSize())); imageFileSize.setText(new ByteSize(slide.getFileSize()).toUnitString(2));
imageFileSize.setVisibility(View.VISIBLE); imageFileSize.setVisibility(View.VISIBLE);
} else { } else {
imageFileSize.setVisibility(View.GONE); imageFileSize.setVisibility(View.GONE);
@@ -445,7 +446,7 @@ final class MediaGalleryAllAdapter extends StickyHeaderGridAdapter {
private String getLine2(@NonNull Context context, @NonNull MediaTable.MediaRecord mediaRecord, @NonNull Slide slide) { private String getLine2(@NonNull Context context, @NonNull MediaTable.MediaRecord mediaRecord, @NonNull Slide slide) {
return context.getString(R.string.MediaOverviewActivity_detail_line_3_part, return context.getString(R.string.MediaOverviewActivity_detail_line_3_part,
Util.getPrettyFileSize(slide.getFileSize()), new ByteSize(slide.getFileSize()).toUnitString(2),
getFileTypeDescription(context, slide), getFileTypeDescription(context, slide),
DateUtils.formatDateWithoutDayOfWeek(Locale.getDefault(), mediaRecord.getDate())); DateUtils.formatDateWithoutDayOfWeek(Locale.getDefault(), mediaRecord.getDate()));
} }

View File

@@ -29,6 +29,7 @@ import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.codewaves.stickyheadergrid.StickyHeaderGridLayoutManager; import com.codewaves.stickyheadergrid.StickyHeaderGridLayoutManager;
import org.signal.core.util.ByteSize;
import org.signal.core.util.DimensionUnit; import org.signal.core.util.DimensionUnit;
import org.signal.core.util.concurrent.LifecycleDisposable; import org.signal.core.util.concurrent.LifecycleDisposable;
import org.signal.core.util.logging.Log; import org.signal.core.util.logging.Log;
@@ -329,7 +330,7 @@ public final class MediaOverviewPageFragment extends Fragment
return getResources().getQuantityString(R.plurals.MediaOverviewActivity_d_selected_s, return getResources().getQuantityString(R.plurals.MediaOverviewActivity_d_selected_s,
mediaCount, mediaCount,
mediaCount, mediaCount,
Util.getPrettyFileSize(totalFileSize)); new ByteSize(totalFileSize).toUnitString());
} }
private MediaGalleryAllAdapter getListAdapter() { private MediaGalleryAllAdapter getListAdapter() {

View File

@@ -8,12 +8,12 @@ import android.view.View
import android.widget.TextView import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import org.signal.core.util.bytes
import org.signal.core.util.getParcelableCompat import org.signal.core.util.getParcelableCompat
import org.signal.core.util.logging.Log import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.mms.PartAuthority import org.thoughtcrime.securesms.mms.PartAuthority
import org.thoughtcrime.securesms.util.MediaUtil import org.thoughtcrime.securesms.util.MediaUtil
import org.thoughtcrime.securesms.util.Util
import java.io.IOException import java.io.IOException
import java.util.Optional import java.util.Optional
@@ -54,7 +54,7 @@ class MediaSendDocumentFragment : Fragment(R.layout.mediasend_document_fragment)
if (fileInfo != null) { if (fileInfo != null) {
media.setFileName(fileInfo.first) media.setFileName(fileInfo.first)
name.text = fileInfo.first ?: getString(R.string.DocumentView_unnamed_file) name.text = fileInfo.first ?: getString(R.string.DocumentView_unnamed_file)
size.text = Util.getPrettyFileSize(fileInfo.second) size.text = fileInfo.second.bytes.toUnitString()
val extensionText: String = MediaUtil.getFileType(requireContext(), Optional.ofNullable(fileInfo.first), media.uri).orElse("") val extensionText: String = MediaUtil.getFileType(requireContext(), Optional.ofNullable(fileInfo.first), media.uri).orElse("")
if (extensionText.length <= 3) { if (extensionText.length <= 3) {

View File

@@ -32,6 +32,7 @@ import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.imageview.ShapeableImageView import com.google.android.material.imageview.ShapeableImageView
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import org.signal.core.util.bytes
import org.signal.core.util.concurrent.LifecycleDisposable import org.signal.core.util.concurrent.LifecycleDisposable
import org.signal.core.util.concurrent.SimpleTask import org.signal.core.util.concurrent.SimpleTask
import org.signal.core.util.isNotNullOrBlank import org.signal.core.util.isNotNullOrBlank
@@ -60,7 +61,6 @@ import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.scribbles.ImageEditorFragment import org.thoughtcrime.securesms.scribbles.ImageEditorFragment
import org.thoughtcrime.securesms.util.BottomSheetUtil import org.thoughtcrime.securesms.util.BottomSheetUtil
import org.thoughtcrime.securesms.util.MediaUtil import org.thoughtcrime.securesms.util.MediaUtil
import org.thoughtcrime.securesms.util.MemoryUnitFormat
import org.thoughtcrime.securesms.util.SystemWindowInsetsSetter import org.thoughtcrime.securesms.util.SystemWindowInsetsSetter
import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter
import org.thoughtcrime.securesms.util.fragments.requireListener import org.thoughtcrime.securesms.util.fragments.requireListener
@@ -600,7 +600,7 @@ class MediaReviewFragment : Fragment(R.layout.v2_media_review_fragment), Schedul
videoSizeHint.text = if (state.isVideoTrimmingVisible) { videoSizeHint.text = if (state.isVideoTrimmingVisible) {
val seconds = trimData.getDuration().inWholeSeconds val seconds = trimData.getDuration().inWholeSeconds
val bytes = TranscodingQuality.createFromPreset(state.transcodingPreset, trimData.getDuration().inWholeMilliseconds).byteCountEstimate val bytes = TranscodingQuality.createFromPreset(state.transcodingPreset, trimData.getDuration().inWholeMilliseconds).byteCountEstimate
String.format(Locale.getDefault(), "%d:%02d • %s", seconds / 60, seconds % 60, MemoryUnitFormat.formatBytes(bytes, MemoryUnitFormat.MEGA_BYTES, true)) String.format(Locale.getDefault(), "%d:%02d • %s", seconds / 60, seconds % 60, bytes.bytes.toUnitString())
} else { } else {
null null
} }

View File

@@ -367,8 +367,8 @@ private fun RestoreProgressDialog(restoreProgress: RestoreV2Event?) {
) )
if (restoreProgress != null) { if (restoreProgress != null) {
val progressBytes = restoreProgress.count.toUnitString(maxPlaces = 2) val progressBytes = restoreProgress.count.toUnitString()
val totalBytes = restoreProgress.estimatedTotalCount.toUnitString(maxPlaces = 2) val totalBytes = restoreProgress.estimatedTotalCount.toUnitString()
Text( Text(
text = stringResource(id = R.string.RemoteRestoreActivity__s_of_s_s, progressBytes, totalBytes, "%.2f%%".format(restoreProgress.getProgress())), text = stringResource(id = R.string.RemoteRestoreActivity__s_of_s_s, progressBytes, totalBytes, "%.2f%%".format(restoreProgress.getProgress())),
style = MaterialTheme.typography.bodySmall, style = MaterialTheme.typography.bodySmall,

View File

@@ -20,6 +20,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode import org.greenrobot.eventbus.ThreadMode
import org.signal.core.util.bytes
import org.signal.core.util.logging.Log import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.LoggingFragment import org.thoughtcrime.securesms.LoggingFragment
import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.R
@@ -33,7 +34,6 @@ import org.thoughtcrime.securesms.restore.RestoreRepository
import org.thoughtcrime.securesms.restore.RestoreViewModel import org.thoughtcrime.securesms.restore.RestoreViewModel
import org.thoughtcrime.securesms.util.BackupUtil import org.thoughtcrime.securesms.util.BackupUtil
import org.thoughtcrime.securesms.util.DateUtils import org.thoughtcrime.securesms.util.DateUtils
import org.thoughtcrime.securesms.util.Util
import org.thoughtcrime.securesms.util.ViewModelFactory import org.thoughtcrime.securesms.util.ViewModelFactory
import org.thoughtcrime.securesms.util.ViewUtil import org.thoughtcrime.securesms.util.ViewUtil
import org.thoughtcrime.securesms.util.visible import org.thoughtcrime.securesms.util.visible
@@ -218,7 +218,7 @@ class RestoreLocalBackupFragment : LoggingFragment(R.layout.fragment_restore_loc
private fun presentBackupFileInfo(backupSize: Long, backupTimestamp: Long) { private fun presentBackupFileInfo(backupSize: Long, backupTimestamp: Long) {
if (backupSize > 0) { if (backupSize > 0) {
binding.backupSizeText.text = getString(R.string.RegistrationActivity_backup_size_s, Util.getPrettyFileSize(backupSize)) binding.backupSizeText.text = getString(R.string.RegistrationActivity_backup_size_s, backupSize.bytes.toUnitString())
} }
if (backupTimestamp > 0) { if (backupTimestamp > 0) {

View File

@@ -18,6 +18,7 @@ import com.pnikosis.materialishprogress.ProgressWheel;
import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode; import org.greenrobot.eventbus.ThreadMode;
import org.signal.core.util.ByteSize;
import org.signal.core.util.logging.Log; import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.attachments.Attachment; import org.thoughtcrime.securesms.attachments.Attachment;
@@ -176,7 +177,7 @@ public class ViewOnceMessageView extends LinearLayout {
if (messageRecord.getSlideDeck().getThumbnailSlide() == null) return ""; if (messageRecord.getSlideDeck().getThumbnailSlide() == null) return "";
long size = messageRecord.getSlideDeck().getThumbnailSlide().getFileSize(); long size = messageRecord.getSlideDeck().getThumbnailSlide().getFileSize();
return Util.getPrettyFileSize(size); return new ByteSize(size).toUnitString(2);
} }
private static @StringRes int getDescriptionId(@NonNull MmsMessageRecord messageRecord) { private static @StringRes int getDescriptionId(@NonNull MmsMessageRecord messageRecord) {

View File

@@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.stories.viewer.info
import android.view.View import android.view.View
import android.widget.TextView import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import org.signal.core.util.bytes
import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.util.DateUtils import org.thoughtcrime.securesms.util.DateUtils
import org.thoughtcrime.securesms.util.Util import org.thoughtcrime.securesms.util.Util
@@ -60,7 +61,7 @@ object StoryInfoHeader {
if (model.size > 0L) { if (model.size > 0L) {
sizeView.visible = true sizeView.visible = true
sizeHeader.visible = true sizeHeader.visible = true
sizeView.text = Util.getPrettyFileSize(model.size) sizeView.text = model.size.bytes.toUnitString()
} else { } else {
sizeView.visible = false sizeView.visible = false
sizeHeader.visible = false sizeHeader.visible = false

View File

@@ -1,58 +0,0 @@
package org.thoughtcrime.securesms.util;
import androidx.annotation.NonNull;
import java.text.DecimalFormat;
/**
* Used for the pretty formatting of bytes for user display.
*/
public enum MemoryUnitFormat {
BYTES(" B"),
KILO_BYTES(" kB"),
MEGA_BYTES(" MB"),
GIGA_BYTES(" GB"),
TERA_BYTES(" TB");
private static final DecimalFormat ONE_DP = new DecimalFormat("#,##0.0");
private static final DecimalFormat OPTIONAL_ONE_DP = new DecimalFormat("#,##0.#");
private final String unitString;
MemoryUnitFormat(String unitString) {
this.unitString = unitString;
}
public double fromBytes(long bytes) {
return bytes / Math.pow(1000, ordinal());
}
/**
* Creates a string suitable to present to the user from the specified {@param bytes}.
* It will pick a suitable unit of measure to display depending on the size of the bytes.
* It will not select a unit of measure lower than the specified {@param minimumUnit}.
*
* @param forceOneDp If true, will include 1 decimal place, even if 0. If false, will only show 1 dp when it's non-zero.
*/
public static String formatBytes(long bytes, @NonNull MemoryUnitFormat minimumUnit, boolean forceOneDp) {
if (bytes <= 0) bytes = 0;
int ordinal = bytes != 0 ? (int) (Math.log10(bytes) / 3) : 0;
if (ordinal >= MemoryUnitFormat.values().length) {
ordinal = MemoryUnitFormat.values().length - 1;
}
MemoryUnitFormat unit = MemoryUnitFormat.values()[ordinal];
if (unit.ordinal() < minimumUnit.ordinal()) {
unit = minimumUnit;
}
return (forceOneDp ? ONE_DP : OPTIONAL_ONE_DP).format(unit.fromBytes(bytes)) + unit.unitString;
}
public static String formatBytes(long bytes) {
return formatBytes(bytes, BYTES, false);
}
}

View File

@@ -187,18 +187,10 @@ public class Util {
return spanned; return spanned;
} }
public static @NonNull String toIsoString(byte[] bytes) {
return new String(bytes, StandardCharsets.ISO_8859_1);
}
public static byte[] toIsoBytes(String isoString) { public static byte[] toIsoBytes(String isoString) {
return isoString.getBytes(StandardCharsets.ISO_8859_1); return isoString.getBytes(StandardCharsets.ISO_8859_1);
} }
public static byte[] toUtf8Bytes(String utf8String) {
return utf8String.getBytes(StandardCharsets.UTF_8);
}
public static void wait(Object lock, long timeout) { public static void wait(Object lock, long timeout) {
try { try {
lock.wait(timeout); lock.wait(timeout);
@@ -371,10 +363,6 @@ public class Util {
} }
} }
public static <T> T getRandomElement(T[] elements) {
return elements[new SecureRandom().nextInt(elements.length)];
}
public static <T> T getRandomElement(List<T> elements) { public static <T> T getRandomElement(List<T> elements) {
return elements.get(new SecureRandom().nextInt(elements.size())); return elements.get(new SecureRandom().nextInt(elements.size()));
} }
@@ -448,38 +436,10 @@ public class Util {
return (int)value; return (int)value;
} }
public static boolean isEquals(@Nullable Long first, long second) {
return first != null && first == second;
}
public static String getPrettyFileSize(long sizeBytes) {
return MemoryUnitFormat.formatBytes(sizeBytes);
}
public static void copyToClipboard(@NonNull Context context, @NonNull CharSequence text) { public static void copyToClipboard(@NonNull Context context, @NonNull CharSequence text) {
ServiceUtil.getClipboardManager(context).setPrimaryClip(ClipData.newPlainText(COPY_LABEL, text)); ServiceUtil.getClipboardManager(context).setPrimaryClip(ClipData.newPlainText(COPY_LABEL, text));
} }
@SafeVarargs
public static <T> List<T> concatenatedList(Collection <T>... items) {
final List<T> concat = new ArrayList<>(Stream.of(items).reduce(0, (sum, list) -> sum + list.size()));
for (Collection<T> list : items) {
concat.addAll(list);
}
return concat;
}
public static boolean isLong(String value) {
try {
Long.parseLong(value);
return true;
} catch (NumberFormatException e) {
return false;
}
}
public static int parseInt(String integer, int defaultValue) { public static int parseInt(String integer, int defaultValue) {
try { try {
return Integer.parseInt(integer); return Integer.parseInt(integer);

View File

@@ -76,7 +76,8 @@ class ByteSize(val bytes: Long) {
} }
} }
fun toUnitString(maxPlaces: Int = 1, spaced: Boolean = true): String { @JvmOverloads
fun toUnitString(maxPlaces: Int = 2, spaced: Boolean = true): String {
val (size, unit) = getLargestNonZeroValue() val (size, unit) = getLargestNonZeroValue()
val formatter = NumberFormat.getInstance().apply { val formatter = NumberFormat.getInstance().apply {