Skip to content

Commit

Permalink
Merge pull request #822 from nextcloud-libraries/fix/files-sizes
Browse files Browse the repository at this point in the history
fix!(humanFileSize): Revert changes to default file sizes
  • Loading branch information
susnux committed Nov 3, 2023
2 parents 5a568e2 + 55065db commit 29c15fc
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 18 deletions.
22 changes: 14 additions & 8 deletions __tests__/humanFileSize.spec.ts
Expand Up @@ -4,8 +4,8 @@ import { formatFileSize, parseFileSize } from '../lib/humanfilesize'

describe('humanFileSize', () => {
describe('formatFileSize', () => {
it('renders binary sizes by default', () => {
expect(formatFileSize(2048)).toBe('2 KiB')
it('renders binary size with decimal units by default', () => {
expect(formatFileSize(2048)).toBe('2 KB')
})

it('renders file sizes with the correct unit', function() {
Expand All @@ -32,12 +32,14 @@ describe('humanFileSize', () => {
[128000000000000, '116.4 TiB'],
[128000000000000.0, '116.4 TiB'],
[128000000000000000.0, '113.7 PiB'],
]
] as const
for (let i = 0; i < dataDecimal.length; i++) {
expect(formatFileSize(dataDecimal[i][0], false, false)).toEqual(dataDecimal[i][1])
expect(formatFileSize(dataDecimal[i][0], false, false, true)).toEqual(dataDecimal[i][1])
}
for (let i = 0; i < dataBinary.length; i++) {
expect(formatFileSize(dataBinary[i][0], false, true)).toEqual(dataBinary[i][1])
// Binary sizes but decimal units
expect(formatFileSize(dataBinary[i][0], false, false)).toEqual(dataBinary[i][1].replace('i', ''))
}
})

Expand All @@ -61,12 +63,14 @@ describe('humanFileSize', () => {
[128000000000000, '116.4 TiB'],
[128000000000000.0, '116.4 TiB'],
[128000000000000000.0, '113.7 PiB'],
]
] as const
for (let i = 0; i < dataDecimal.length; i++) {
expect(formatFileSize(dataDecimal[i][0], true, false)).toEqual(dataDecimal[i][1])
expect(formatFileSize(dataDecimal[i][0], true, false, true)).toEqual(dataDecimal[i][1])
}
for (let i = 0; i < dataBinary.length; i++) {
expect(formatFileSize(dataBinary[i][0], true, true)).toEqual(dataBinary[i][1])
// Binary sizes but decimal units
expect(formatFileSize(dataBinary[i][0], true, false)).toEqual(dataBinary[i][1].replace('i', ''))
}
})

Expand Down Expand Up @@ -95,12 +99,14 @@ describe('humanFileSize', () => {
[128000000000000, '116,4 TiB'],
[128000000000000.0, '116,4 TiB'],
[128000000000000000.0, '113,7 PiB'],
]
] as const
for (let i = 0; i < dataDecimal.length; i++) {
expect(formatFileSize(dataDecimal[i][0], false, false)).toEqual(dataDecimal[i][1])
expect(formatFileSize(dataDecimal[i][0], false, false, true)).toEqual(dataDecimal[i][1])
}
for (let i = 0; i < dataBinary.length; i++) {
expect(formatFileSize(dataBinary[i][0], false, true)).toEqual(dataBinary[i][1])
// Binary sizes but decimal units
expect(formatFileSize(dataBinary[i][0], false, false)).toEqual(dataBinary[i][1].replace('i', ''))
}
})
})
Expand Down
22 changes: 12 additions & 10 deletions lib/humanfilesize.ts
Expand Up @@ -29,28 +29,30 @@ const humanListBinary = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB']
/**
* Format a file size in a human-like format. e.g. 42GB
*
* The default for Nextcloud is like Windows using binary sizes but showing decimal units,
* meaning 1024 bytes will show as 1KB instead of 1KiB or like on Apple 1.02 KB
*
* @param size in bytes
* @param skipSmallSizes avoid rendering tiny sizes and return '< 1 KB' instead
* @param binaryPrefixes True if size base 2 (and binary prefixes like `KiB`) should be used
* @param binaryPrefixes True if size binary prefixes like `KiB` should be used as per IEC 80000-13
* @param base1000 Set to true to use base 1000 as per SI or used by Apple (default is base 1024 like Linux or Windows)
*/
export function formatFileSize(size: number|string, skipSmallSizes = false, binaryPrefixes = true): string {
export function formatFileSize(size: number|string, skipSmallSizes = false, binaryPrefixes = false, base1000 = false): string {
// Binary prefixes only work with base 1024
binaryPrefixes = binaryPrefixes && !base1000

if (typeof size === 'string') {
size = Number(size)
}

/*
* @note This block previously used Log base 1024, per IEC 80000-13;
* however, the wrong prefix was used. Now we use decimal calculation
* with base 1000 per the SI. Base 1024 calculation with binary
* prefixes is optional, but has yet to be added to the UI.
*/
// Calculate Log with base 1024 or 1000: size = base ** order
let order = size > 0 ? Math.floor(Math.log(size) / Math.log(binaryPrefixes ? 1024 : 1000)) : 0
let order = size > 0 ? Math.floor(Math.log(size) / Math.log(base1000 ? 1000 : 1024)) : 0

// Stay in range of the byte sizes that are defined
order = Math.min((binaryPrefixes ? humanListBinary.length : humanList.length) - 1, order)

const readableFormat = binaryPrefixes ? humanListBinary[order] : humanList[order]
let relativeSize = (size / Math.pow(binaryPrefixes ? 1024 : 1000, order)).toFixed(1)
let relativeSize = (size / Math.pow(base1000 ? 1000 : 1024, order)).toFixed(1)

if (skipSmallSizes === true && order === 0) {
return (relativeSize !== '0.0' ? '< 1 ' : '0 ') + (binaryPrefixes ? humanListBinary[1] : humanList[1])
Expand Down

0 comments on commit 29c15fc

Please sign in to comment.