fix: display unlimited quota (∞) when storage_quota_bytes = 0

- Added formatQuotaSize() function to display ∞ for unlimited (0) quota
- Added format_quota_size() Rust function matching JavaScript behavior
- Updated quota defaulting logic from '||' to '== null' check
- This allows 0 (unlimited) to pass through while defaulting to 10 GB
  only when the value is null/undefined
- Call sites now use dedicated formatQuotaSize() or format_quota_size()
  instead of options parameter for cleaner API
This commit is contained in:
George Wu
2026-02-20 19:02:01 -08:00
parent 269a5fe940
commit 283a80a302
4 changed files with 34 additions and 7 deletions
+19
View File
@@ -367,6 +367,16 @@ pub fn format_file_size(bytes: u64) -> String {
format!("{} {}", formatted, SIZES[i])
}
/// Formats a byte count for quota display. When bytes is 0, returns "∞" (unlimited).
///
/// Matches the JavaScript `formatQuotaSize()` output.
pub fn format_quota_size(bytes: u64) -> String {
if bytes == 0 {
return "∞".to_string();
}
format_file_size(bytes)
}
#[cfg(test)]
mod tests {
use super::*;
@@ -382,6 +392,15 @@ mod tests {
assert_eq!(format_file_size(1_073_741_824), "1 GB");
}
#[test]
fn test_format_quota_size() {
// Unlimited quota (0) should show infinity symbol
assert_eq!(format_quota_size(0), "∞");
// Non-zero values should format normally
assert_eq!(format_quota_size(500), "500 Bytes");
assert_eq!(format_quota_size(1_073_741_824), "1 GB");
}
#[test]
fn test_icon_class_for_with_extension_fallback() {
// Specific MIME types
+3 -2
View File
@@ -567,7 +567,8 @@ function updateStorageUsageDisplay(userData) {
// Get values from user data if available
if (userData) {
usedBytes = userData.storage_used_bytes || 0;
quotaBytes = userData.storage_quota_bytes || DEFAULT_QUOTA;
// Use == null to allow 0 (unlimited) to pass through; only default to DEFAULT_QUOTA when null/undefined
quotaBytes = userData.storage_quota_bytes == null ? DEFAULT_QUOTA : userData.storage_quota_bytes;
// Calculate percentage (avoid division by zero)
if (quotaBytes > 0) {
@@ -577,7 +578,7 @@ function updateStorageUsageDisplay(userData) {
// Format the numbers for display
const usedFormatted = formatFileSize(usedBytes);
const quotaFormatted = formatFileSize(quotaBytes);
const quotaFormatted = formatQuotaSize(quotaBytes);
// Update the storage display elements
const storageFill = document.querySelector('.storage-fill');
+5 -5
View File
@@ -135,14 +135,14 @@ function updateUserMenuData() {
}
const usedBytes = userData.storage_used_bytes || 0;
const quotaBytes = userData.storage_quota_bytes || (10 * 1024 * 1024 * 1024);
const quotaBytes = userData.storage_quota_bytes == null ? (10 * 1024 * 1024 * 1024) : userData.storage_quota_bytes;
const percentage = quotaBytes > 0 ? Math.min(Math.round((usedBytes / quotaBytes) * 100), 100) : 0;
if (storageFill) storageFill.style.width = percentage + '%';
if (storageText) {
const used = window.formatFileSize(usedBytes);
const total = window.formatFileSize(quotaBytes);
storageText.textContent = `${percentage}% · ${used} / ${total}`;
const total = window.formatQuotaSize(quotaBytes);
storageText.textContent = `${quotaBytes > 0 ? `${percentage}% · ` : ''}${used} / ${total}`;
}
}
@@ -169,7 +169,7 @@ function showUserProfileModal() {
const role = userData.role || 'user';
const initials = username.substring(0, 2).toUpperCase();
const usedBytes = userData.storage_used_bytes || 0;
const quotaBytes = userData.storage_quota_bytes || (10 * 1024 * 1024 * 1024);
const quotaBytes = userData.storage_quota_bytes == null ? (10 * 1024 * 1024 * 1024) : userData.storage_quota_bytes;
const percentage = quotaBytes > 0 ? Math.min(Math.round((usedBytes / quotaBytes) * 100), 100) : 0;
const barColor = percentage > 90 ? '#ef4444' : percentage > 70 ? '#f59e0b' : '#22c55e';
@@ -200,7 +200,7 @@ function showUserProfileModal() {
<div style="background:#f1f5f9;border-radius:6px;height:8px;overflow:hidden;margin-bottom:4px">
<div style="height:100%;width:${percentage}%;background:${barColor};border-radius:6px;transition:width .3s"></div>
</div>
<div style="font-size:12px;color:#64748b;text-align:right">${percentage}% · ${window.formatFileSize(usedBytes)} / ${quotaBytes > 0 ? window.formatFileSize(quotaBytes) : '∞'}</div>
<div style="font-size:12px;color:#64748b;text-align:right">${percentage}% · ${window.formatFileSize(usedBytes)} / ${window.formatQuotaSize(quotaBytes)}</div>
</div>
<div style="padding:0 20px 16px;display:flex;justify-content:center">
<button id="profile-modal-close" style="padding:8px 24px;border:1px solid #e2e8f0;border-radius:8px;background:#fff;color:#334155;font-size:13px;font-weight:600;cursor:pointer;transition:background .15s">${t('actions.close', 'Close')}</button>
+7
View File
@@ -23,6 +23,12 @@ function formatFileSize(bytes) {
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
/// Formats a byte count for quota display. When bytes is 0, returns "∞" (unlimited).
function formatQuotaSize(bytes) {
if (bytes === 0) return '∞';
return formatFileSize(bytes);
}
function formatDateTime(value) {
if (!value) return '';
let dateValue;
@@ -58,6 +64,7 @@ function isTextViewable(mimeType) {
window.escapeHtml = escapeHtml;
window.formatFileSize = formatFileSize;
window.formatQuotaSize = formatQuotaSize;
window.formatDateTime = formatDateTime;
window.formatDateShort = formatDateShort;
window.isTextViewable = isTextViewable;