mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-20 11:08:31 +00:00
Consistently format byte sizes.
This commit is contained in:
@@ -262,7 +262,7 @@ sealed interface BackupStatusData {
|
||||
class NotEnoughFreeSpace(
|
||||
requiredSpace: ByteSize
|
||||
) : BackupStatusData {
|
||||
val requiredSpace = requiredSpace.toUnitString(maxPlaces = 2)
|
||||
val requiredSpace = requiredSpace.toUnitString()
|
||||
|
||||
override val iconRes: Int = R.drawable.symbol_backup_error_24
|
||||
|
||||
@@ -301,8 +301,8 @@ sealed interface BackupStatusData {
|
||||
@Composable get() = when (restoreStatus) {
|
||||
RestoreStatus.NORMAL -> stringResource(
|
||||
R.string.BackupStatus__status_size_of_size,
|
||||
bytesDownloaded.toUnitString(maxPlaces = 2),
|
||||
bytesTotal.toUnitString(maxPlaces = 2)
|
||||
bytesDownloaded.toUnitString(),
|
||||
bytesTotal.toUnitString()
|
||||
)
|
||||
|
||||
RestoreStatus.LOW_BATTERY -> stringResource(R.string.BackupStatus__status_device_has_low_battery)
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.pnikosis.materialishprogress.ProgressWheel;
|
||||
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
import org.greenrobot.eventbus.ThreadMode;
|
||||
import org.signal.core.util.ByteSize;
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.database.AttachmentTable;
|
||||
@@ -115,7 +116,7 @@ public class DocumentView extends FrameLayout {
|
||||
this.fileName.setText(OptionalUtil.or(documentSlide.getFileName(),
|
||||
documentSlide.getCaption())
|
||||
.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.setOnClickListener(new OpenClickedListener(documentSlide));
|
||||
}
|
||||
|
||||
@@ -103,7 +103,6 @@ import org.thoughtcrime.securesms.keyvalue.protos.ArchiveUploadProgressState
|
||||
import org.thoughtcrime.securesms.payments.FiatMoneyUtil
|
||||
import org.thoughtcrime.securesms.util.DateUtils
|
||||
import org.thoughtcrime.securesms.util.ServiceUtil
|
||||
import org.thoughtcrime.securesms.util.Util
|
||||
import org.thoughtcrime.securesms.util.navigation.safeNavigate
|
||||
import org.thoughtcrime.securesms.util.viewModel
|
||||
import java.math.BigDecimal
|
||||
@@ -610,7 +609,7 @@ private fun LazyListScope.appendBackupDetailsItems(
|
||||
color = MaterialTheme.colorScheme.onSurface
|
||||
)
|
||||
Text(
|
||||
text = Util.getPrettyFileSize(backupMediaSize),
|
||||
text = backupMediaSize.bytes.toUnitString(),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
|
||||
@@ -3,13 +3,13 @@ package org.thoughtcrime.securesms.components.settings.app.data
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.navigation.Navigation
|
||||
import androidx.preference.PreferenceManager
|
||||
import org.signal.core.util.bytes
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.components.settings.DSLConfiguration
|
||||
import org.thoughtcrime.securesms.components.settings.DSLSettingsFragment
|
||||
import org.thoughtcrime.securesms.components.settings.DSLSettingsText
|
||||
import org.thoughtcrime.securesms.components.settings.configure
|
||||
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.navigation.safeNavigate
|
||||
import org.thoughtcrime.securesms.webrtc.CallDataMode
|
||||
@@ -46,7 +46,7 @@ class DataAndStorageSettingsFragment : DSLSettingsFragment(R.string.preferences_
|
||||
return configure {
|
||||
clickPref(
|
||||
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 = {
|
||||
Navigation.findNavController(requireView()).safeNavigate(R.id.action_dataAndStorageSettingsFragment_to_storagePreferenceFragment)
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ import org.signal.core.ui.Scaffolds
|
||||
import org.signal.core.ui.SignalPreview
|
||||
import org.signal.core.ui.Texts
|
||||
import org.signal.core.ui.theme.SignalTheme
|
||||
import org.signal.core.util.bytes
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.billing.upgrade.UpgradeToEnableOptimizedStorageSheet
|
||||
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.preferences.widgets.StorageGraphView
|
||||
import org.thoughtcrime.securesms.util.BottomSheetUtil
|
||||
import org.thoughtcrime.securesms.util.Util
|
||||
import org.thoughtcrime.securesms.util.viewModel
|
||||
import java.text.NumberFormat
|
||||
|
||||
@@ -360,7 +360,7 @@ private fun StorageOverview(
|
||||
)
|
||||
|
||||
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 {
|
||||
|
||||
@@ -35,6 +35,7 @@ import com.annimon.stream.Stream;
|
||||
import com.bumptech.glide.RequestManager;
|
||||
import com.codewaves.stickyheadergrid.StickyHeaderGridAdapter;
|
||||
|
||||
import org.signal.core.util.ByteSize;
|
||||
import org.signal.libsignal.protocol.util.Pair;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.attachments.AttachmentId;
|
||||
@@ -339,7 +340,7 @@ final class MediaGalleryAllAdapter extends StickyHeaderGridAdapter {
|
||||
super.bind(context, mediaRecord, slide);
|
||||
this.slide = slide;
|
||||
if (showFileSizes | detailView) {
|
||||
imageFileSize.setText(Util.getPrettyFileSize(slide.getFileSize()));
|
||||
imageFileSize.setText(new ByteSize(slide.getFileSize()).toUnitString(2));
|
||||
imageFileSize.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
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) {
|
||||
return context.getString(R.string.MediaOverviewActivity_detail_line_3_part,
|
||||
Util.getPrettyFileSize(slide.getFileSize()),
|
||||
new ByteSize(slide.getFileSize()).toUnitString(2),
|
||||
getFileTypeDescription(context, slide),
|
||||
DateUtils.formatDateWithoutDayOfWeek(Locale.getDefault(), mediaRecord.getDate()));
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.codewaves.stickyheadergrid.StickyHeaderGridLayoutManager;
|
||||
|
||||
import org.signal.core.util.ByteSize;
|
||||
import org.signal.core.util.DimensionUnit;
|
||||
import org.signal.core.util.concurrent.LifecycleDisposable;
|
||||
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,
|
||||
mediaCount,
|
||||
mediaCount,
|
||||
Util.getPrettyFileSize(totalFileSize));
|
||||
new ByteSize(totalFileSize).toUnitString());
|
||||
}
|
||||
|
||||
private MediaGalleryAllAdapter getListAdapter() {
|
||||
|
||||
@@ -8,12 +8,12 @@ import android.view.View
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.fragment.app.Fragment
|
||||
import org.signal.core.util.bytes
|
||||
import org.signal.core.util.getParcelableCompat
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.mms.PartAuthority
|
||||
import org.thoughtcrime.securesms.util.MediaUtil
|
||||
import org.thoughtcrime.securesms.util.Util
|
||||
import java.io.IOException
|
||||
import java.util.Optional
|
||||
|
||||
@@ -54,7 +54,7 @@ class MediaSendDocumentFragment : Fragment(R.layout.mediasend_document_fragment)
|
||||
if (fileInfo != null) {
|
||||
media.setFileName(fileInfo.first)
|
||||
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("")
|
||||
if (extensionText.length <= 3) {
|
||||
|
||||
@@ -32,6 +32,7 @@ import androidx.viewpager2.widget.ViewPager2
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.imageview.ShapeableImageView
|
||||
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.SimpleTask
|
||||
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.util.BottomSheetUtil
|
||||
import org.thoughtcrime.securesms.util.MediaUtil
|
||||
import org.thoughtcrime.securesms.util.MemoryUnitFormat
|
||||
import org.thoughtcrime.securesms.util.SystemWindowInsetsSetter
|
||||
import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter
|
||||
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) {
|
||||
val seconds = trimData.getDuration().inWholeSeconds
|
||||
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 {
|
||||
null
|
||||
}
|
||||
|
||||
@@ -367,8 +367,8 @@ private fun RestoreProgressDialog(restoreProgress: RestoreV2Event?) {
|
||||
)
|
||||
|
||||
if (restoreProgress != null) {
|
||||
val progressBytes = restoreProgress.count.toUnitString(maxPlaces = 2)
|
||||
val totalBytes = restoreProgress.estimatedTotalCount.toUnitString(maxPlaces = 2)
|
||||
val progressBytes = restoreProgress.count.toUnitString()
|
||||
val totalBytes = restoreProgress.estimatedTotalCount.toUnitString()
|
||||
Text(
|
||||
text = stringResource(id = R.string.RemoteRestoreActivity__s_of_s_s, progressBytes, totalBytes, "%.2f%%".format(restoreProgress.getProgress())),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
import org.signal.core.util.bytes
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.LoggingFragment
|
||||
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.util.BackupUtil
|
||||
import org.thoughtcrime.securesms.util.DateUtils
|
||||
import org.thoughtcrime.securesms.util.Util
|
||||
import org.thoughtcrime.securesms.util.ViewModelFactory
|
||||
import org.thoughtcrime.securesms.util.ViewUtil
|
||||
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) {
|
||||
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) {
|
||||
|
||||
@@ -18,6 +18,7 @@ import com.pnikosis.materialishprogress.ProgressWheel;
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
import org.greenrobot.eventbus.ThreadMode;
|
||||
import org.signal.core.util.ByteSize;
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.attachments.Attachment;
|
||||
@@ -176,7 +177,7 @@ public class ViewOnceMessageView extends LinearLayout {
|
||||
if (messageRecord.getSlideDeck().getThumbnailSlide() == null) return "";
|
||||
|
||||
long size = messageRecord.getSlideDeck().getThumbnailSlide().getFileSize();
|
||||
return Util.getPrettyFileSize(size);
|
||||
return new ByteSize(size).toUnitString(2);
|
||||
}
|
||||
|
||||
private static @StringRes int getDescriptionId(@NonNull MmsMessageRecord messageRecord) {
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.stories.viewer.info
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import org.signal.core.util.bytes
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.util.DateUtils
|
||||
import org.thoughtcrime.securesms.util.Util
|
||||
@@ -60,7 +61,7 @@ object StoryInfoHeader {
|
||||
if (model.size > 0L) {
|
||||
sizeView.visible = true
|
||||
sizeHeader.visible = true
|
||||
sizeView.text = Util.getPrettyFileSize(model.size)
|
||||
sizeView.text = model.size.bytes.toUnitString()
|
||||
} else {
|
||||
sizeView.visible = false
|
||||
sizeHeader.visible = false
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -187,18 +187,10 @@ public class Util {
|
||||
return spanned;
|
||||
}
|
||||
|
||||
public static @NonNull String toIsoString(byte[] bytes) {
|
||||
return new String(bytes, StandardCharsets.ISO_8859_1);
|
||||
}
|
||||
|
||||
public static byte[] toIsoBytes(String isoString) {
|
||||
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) {
|
||||
try {
|
||||
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) {
|
||||
return elements.get(new SecureRandom().nextInt(elements.size()));
|
||||
}
|
||||
@@ -448,38 +436,10 @@ public class Util {
|
||||
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) {
|
||||
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) {
|
||||
try {
|
||||
return Integer.parseInt(integer);
|
||||
|
||||
@@ -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 formatter = NumberFormat.getInstance().apply {
|
||||
|
||||
Reference in New Issue
Block a user