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:
@@ -367,6 +367,16 @@ pub fn format_file_size(bytes: u64) -> String {
|
|||||||
format!("{} {}", formatted, SIZES[i])
|
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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
@@ -382,6 +392,15 @@ mod tests {
|
|||||||
assert_eq!(format_file_size(1_073_741_824), "1 GB");
|
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]
|
#[test]
|
||||||
fn test_icon_class_for_with_extension_fallback() {
|
fn test_icon_class_for_with_extension_fallback() {
|
||||||
// Specific MIME types
|
// Specific MIME types
|
||||||
|
|||||||
@@ -567,7 +567,8 @@ function updateStorageUsageDisplay(userData) {
|
|||||||
// Get values from user data if available
|
// Get values from user data if available
|
||||||
if (userData) {
|
if (userData) {
|
||||||
usedBytes = userData.storage_used_bytes || 0;
|
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)
|
// Calculate percentage (avoid division by zero)
|
||||||
if (quotaBytes > 0) {
|
if (quotaBytes > 0) {
|
||||||
@@ -577,7 +578,7 @@ function updateStorageUsageDisplay(userData) {
|
|||||||
|
|
||||||
// Format the numbers for display
|
// Format the numbers for display
|
||||||
const usedFormatted = formatFileSize(usedBytes);
|
const usedFormatted = formatFileSize(usedBytes);
|
||||||
const quotaFormatted = formatFileSize(quotaBytes);
|
const quotaFormatted = formatQuotaSize(quotaBytes);
|
||||||
|
|
||||||
// Update the storage display elements
|
// Update the storage display elements
|
||||||
const storageFill = document.querySelector('.storage-fill');
|
const storageFill = document.querySelector('.storage-fill');
|
||||||
|
|||||||
@@ -135,14 +135,14 @@ function updateUserMenuData() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const usedBytes = userData.storage_used_bytes || 0;
|
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 percentage = quotaBytes > 0 ? Math.min(Math.round((usedBytes / quotaBytes) * 100), 100) : 0;
|
||||||
|
|
||||||
if (storageFill) storageFill.style.width = percentage + '%';
|
if (storageFill) storageFill.style.width = percentage + '%';
|
||||||
if (storageText) {
|
if (storageText) {
|
||||||
const used = window.formatFileSize(usedBytes);
|
const used = window.formatFileSize(usedBytes);
|
||||||
const total = window.formatFileSize(quotaBytes);
|
const total = window.formatQuotaSize(quotaBytes);
|
||||||
storageText.textContent = `${percentage}% · ${used} / ${total}`;
|
storageText.textContent = `${quotaBytes > 0 ? `${percentage}% · ` : ''}${used} / ${total}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,7 +169,7 @@ function showUserProfileModal() {
|
|||||||
const role = userData.role || 'user';
|
const role = userData.role || 'user';
|
||||||
const initials = username.substring(0, 2).toUpperCase();
|
const initials = username.substring(0, 2).toUpperCase();
|
||||||
const usedBytes = userData.storage_used_bytes || 0;
|
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 percentage = quotaBytes > 0 ? Math.min(Math.round((usedBytes / quotaBytes) * 100), 100) : 0;
|
||||||
const barColor = percentage > 90 ? '#ef4444' : percentage > 70 ? '#f59e0b' : '#22c55e';
|
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="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 style="height:100%;width:${percentage}%;background:${barColor};border-radius:6px;transition:width .3s"></div>
|
||||||
</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>
|
||||||
<div style="padding:0 20px 16px;display:flex;justify-content:center">
|
<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>
|
<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>
|
||||||
|
|||||||
@@ -23,6 +23,12 @@ function formatFileSize(bytes) {
|
|||||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
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) {
|
function formatDateTime(value) {
|
||||||
if (!value) return '';
|
if (!value) return '';
|
||||||
let dateValue;
|
let dateValue;
|
||||||
@@ -58,6 +64,7 @@ function isTextViewable(mimeType) {
|
|||||||
|
|
||||||
window.escapeHtml = escapeHtml;
|
window.escapeHtml = escapeHtml;
|
||||||
window.formatFileSize = formatFileSize;
|
window.formatFileSize = formatFileSize;
|
||||||
|
window.formatQuotaSize = formatQuotaSize;
|
||||||
window.formatDateTime = formatDateTime;
|
window.formatDateTime = formatDateTime;
|
||||||
window.formatDateShort = formatDateShort;
|
window.formatDateShort = formatDateShort;
|
||||||
window.isTextViewable = isTextViewable;
|
window.isTextViewable = isTextViewable;
|
||||||
|
|||||||
Reference in New Issue
Block a user