Skip to content

Commit 3052a14

Browse files
authored
feat: make byte size units translatable (#5969)
Make byte size units translatable
1 parent e8665f4 commit 3052a14

21 files changed

Lines changed: 214 additions & 222 deletions

File tree

apps/app-frontend/src/App.vue

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,10 @@ import {
5151
providePageContext,
5252
providePopupNotificationManager,
5353
useDebugLogger,
54+
useFormatBytes,
5455
useVIntl,
5556
} from '@modrinth/ui'
56-
import { formatBytes, renderString } from '@modrinth/utils'
57+
import { renderString } from '@modrinth/utils'
5758
import { useQuery, useQueryClient } from '@tanstack/vue-query'
5859
import { getVersion } from '@tauri-apps/api/app'
5960
import { invoke } from '@tauri-apps/api/core'
@@ -262,6 +263,8 @@ onUnmounted(async () => {
262263
})
263264
264265
const { formatMessage } = useVIntl()
266+
const formatBytes = useFormatBytes()
267+
265268
const messages = defineMessages({
266269
updateInstalledToastTitle: {
267270
id: 'app.update.complete-toast.title',

apps/app-frontend/src/pages/project/Version.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,9 +176,10 @@ import {
176176
ButtonStyled,
177177
Card,
178178
CopyCode,
179+
useFormatBytes,
179180
useFormatDateTime,
180181
} from '@modrinth/ui'
181-
import { formatBytes, renderString } from '@modrinth/utils'
182+
import { renderString } from '@modrinth/utils'
182183
import { computed, ref, watch } from 'vue'
183184
import { useRoute } from 'vue-router'
184185
@@ -191,6 +192,7 @@ const formatDateTime = useFormatDateTime({
191192
timeStyle: 'short',
192193
dateStyle: 'long',
193194
})
195+
const formatBytes = useFormatBytes()
194196
195197
const breadcrumbs = useBreadcrumbs()
196198

apps/frontend/src/components/ui/FileInput.vue

Lines changed: 47 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -17,74 +17,60 @@
1717
</label>
1818
</template>
1919

20-
<script>
21-
import { fileIsValid } from '~/helpers/fileUtils.js'
20+
<script setup lang="ts">
21+
import { useFormatBytes } from '@modrinth/ui'
22+
import { fileIsValid } from '@modrinth/utils'
23+
import { ref } from 'vue'
2224
23-
export default {
24-
components: {},
25-
props: {
26-
prompt: {
27-
type: String,
28-
default: 'Select file',
29-
},
30-
multiple: {
31-
type: Boolean,
32-
default: false,
33-
},
34-
accept: {
35-
type: String,
36-
default: null,
37-
},
25+
const props = withDefaults(
26+
defineProps<{
27+
prompt?: string
28+
multiple?: boolean
29+
accept?: string
3830
/**
3931
* The max file size in bytes
4032
*/
41-
maxSize: {
42-
type: Number,
43-
default: null,
44-
},
45-
showIcon: {
46-
type: Boolean,
47-
default: true,
48-
},
49-
shouldAlwaysReset: {
50-
type: Boolean,
51-
default: false,
52-
},
53-
longStyle: {
54-
type: Boolean,
55-
default: false,
56-
},
57-
disabled: {
58-
type: Boolean,
59-
default: false,
60-
},
33+
maxSize?: number | null
34+
showIcon?: boolean
35+
shouldAlwaysReset?: boolean
36+
longStyle?: boolean
37+
disabled?: boolean
38+
}>(),
39+
{
40+
prompt: 'Select file',
41+
multiple: false,
42+
showIcon: true,
43+
shouldAlwaysReset: false,
44+
longStyle: false,
45+
disabled: false,
6146
},
62-
emits: ['change'],
63-
data() {
64-
return {
65-
files: [],
66-
}
67-
},
68-
methods: {
69-
addFiles(files, shouldNotReset) {
70-
if (!shouldNotReset || this.shouldAlwaysReset) {
71-
this.files = files
72-
}
47+
)
7348
74-
const validationOptions = { maxSize: this.maxSize, alertOnInvalid: true }
75-
this.files = [...this.files].filter((file) => fileIsValid(file, validationOptions))
49+
const emit = defineEmits<{ change: [files: File[]] }>()
7650
77-
if (this.files.length > 0) {
78-
this.$emit('change', this.files)
79-
}
80-
},
81-
handleDrop(e) {
82-
this.addFiles(e.dataTransfer.files)
83-
},
84-
handleChange(e) {
85-
this.addFiles(e.target.files)
86-
},
87-
},
51+
const formatBytes = useFormatBytes()
52+
53+
const files = ref<File[]>([])
54+
55+
function addFiles(incoming: FileList, shouldNotReset = false) {
56+
if (!shouldNotReset || props.shouldAlwaysReset) {
57+
files.value = Array.from(incoming)
58+
}
59+
const validationOptions = { maxSize: props.maxSize, alertOnInvalid: true }
60+
files.value = files.value.filter((file) => fileIsValid(file, validationOptions, formatBytes))
61+
if (files.value.length > 0) {
62+
emit('change', files.value)
63+
}
64+
}
65+
66+
function handleDrop(e: DragEvent) {
67+
addFiles(e.dataTransfer!.files)
68+
}
69+
70+
function handleChange(e: Event) {
71+
const input = e.target as HTMLInputElement
72+
if (!input.files) return
73+
addFiles(input.files)
8874
}
8975
</script>
9076

apps/frontend/src/components/ui/moderation/ModerationTechRevCard.vue

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import {
2828
injectNotificationManager,
2929
OverflowMenu,
3030
type OverflowMenuOption,
31+
useFormatBytes,
3132
useFormatDateTime,
3233
} from '@modrinth/ui'
3334
import { NavTabs } from '@modrinth/ui'
@@ -56,6 +57,7 @@ const formatDateTimeUtc = useFormatDateTime({
5657
timeZoneName: 'short',
5758
timeZone: 'UTC',
5859
})
60+
const formatBytes = useFormatBytes()
5961
6062
type FlattenedFileReport = Labrinth.TechReview.Internal.FileReport & {
6163
id: string
@@ -362,12 +364,6 @@ const formattedDate = computed(() => {
362364
return `${diffDays} days ago`
363365
})
364366
365-
function formatFileSize(bytes: number): string {
366-
if (bytes < 1024) return `${bytes} B`
367-
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(2)} KiB`
368-
return `${(bytes / (1024 * 1024)).toFixed(2)} MiB`
369-
}
370-
371367
function viewFileFlags(file: FlattenedFileReport) {
372368
selectedFileId.value = file.id
373369
currentTab.value = 'File'
@@ -851,7 +847,7 @@ const reviewSummaryPreview = computed(() => {
851847
const fileVerdict = fileUnsafe > 0 ? 'Unsafe' : 'Safe'
852848
853849
markdown += `### ${fileData.fileName}\n`
854-
markdown += `> ${formatFileSize(fileData.fileSize)} • ${fileData.decisions.length} issues • Max severity: ${fileData.maxSeverity} • **Verdict:** ${fileVerdict}\n\n`
850+
markdown += `> ${formatBytes(fileData.fileSize)} • ${fileData.decisions.length} issues • Max severity: ${fileData.maxSeverity} • **Verdict:** ${fileVerdict}\n\n`
855851
markdown += `<details>\n<summary>Issues (${fileSafe} safe, ${fileUnsafe} unsafe)</summary>\n\n`
856852
markdown += `| Class | Issue Type | Severity | Decision |\n`
857853
markdown += `|-------|------------|----------|----------|\n`
@@ -1150,7 +1146,7 @@ async function handleSubmitReview(verdict: 'safe' | 'unsafe') {
11501146
</span>
11511147
<div class="rounded-full border border-solid border-surface-5 bg-surface-3 px-2.5 py-1">
11521148
<span class="text-sm font-medium text-secondary">{{
1153-
formatFileSize(file.file_size)
1149+
formatBytes(file.file_size)
11541150
}}</span>
11551151
</div>
11561152
<div

apps/frontend/src/helpers/fileUtils.js

Lines changed: 0 additions & 32 deletions
This file was deleted.

apps/frontend/src/pages/[type]/[id]/settings/index.vue

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,11 @@
146146
const input = e.target
147147
if (input.files?.length) {
148148
if (
149-
fileIsValid(input.files[0], { maxSize: 524288000, alertOnInvalid: true })
149+
fileIsValid(
150+
input.files[0],
151+
{ maxSize: 524288000, alertOnInvalid: true },
152+
formatBytes,
153+
)
150154
)
151155
showBannerPreview(Array.from(input.files))
152156
}
@@ -379,6 +383,7 @@ import {
379383
StyledInput,
380384
Toggle,
381385
UnsavedChangesPopup,
386+
useFormatBytes,
382387
usePageLeaveSafety,
383388
} from '@modrinth/ui'
384389
import { fileIsValid, formatProjectStatus, formatProjectType } from '@modrinth/utils'
@@ -405,6 +410,8 @@ const flags = useFeatureFlags()
405410
const tags = useGeneratedState()
406411
const router = useNativeRouter()
407412
413+
const formatBytes = useFormatBytes()
414+
408415
const name = ref(project.value.title)
409416
const slug = ref(project.value.slug)
410417
const summary = ref(project.value.description)

apps/frontend/src/pages/[type]/[id]/version/[version].vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,9 +442,10 @@ import {
442442
MultiSelect,
443443
PROJECT_DEP_MARKER_QUERY,
444444
StyledInput,
445+
useFormatBytes,
445446
useFormatDateTime,
446447
} from '@modrinth/ui'
447-
import { formatBytes, renderHighlightedString } from '@modrinth/utils'
448+
import { renderHighlightedString } from '@modrinth/utils'
448449
449450
import Breadcrumbs from '~/components/ui/Breadcrumbs.vue'
450451
import CreateProjectVersionModal from '~/components/ui/create-project-version/CreateProjectVersionModal.vue'
@@ -473,6 +474,7 @@ const formatDateTime = useFormatDateTime({
473474
dateStyle: 'long',
474475
})
475476
const formatDate = useFormatDateTime({ dateStyle: 'medium' })
477+
const formatBytes = useFormatBytes()
476478
477479
// Helper for accessing nuxt app $formatVersion
478480
const formatVersionDisplay = (versions: string[]) => (data as any).$formatVersion(versions)

apps/frontend/src/pages/admin/file_lookup.vue

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,19 @@
8181

8282
<script setup lang="ts">
8383
import { FileIcon, SpinnerIcon, UploadIcon } from '@modrinth/assets'
84-
import { Admonition, Avatar, CopyCode, injectNotificationManager } from '@modrinth/ui'
85-
import { formatBytes, type Project, type Version } from '@modrinth/utils'
84+
import {
85+
Admonition,
86+
Avatar,
87+
CopyCode,
88+
injectNotificationManager,
89+
useFormatBytes,
90+
} from '@modrinth/ui'
91+
import type { Project, Version } from '@modrinth/utils'
8692
8793
const { addNotification } = injectNotificationManager()
8894
95+
const formatBytes = useFormatBytes()
96+
8997
const fileInput = ref<HTMLInputElement>()
9098
const selectedFile = ref<File | null>(null)
9199
const fileHashes = ref<{

packages/ui/src/components/base/AppearingProgressBar.vue

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,10 @@
3030
</template>
3131

3232
<script setup lang="ts">
33-
import { formatBytes } from '@modrinth/utils'
3433
import { computed, onUnmounted, ref, watch } from 'vue'
3534
35+
import { useFormatBytes } from '#ui/composables'
36+
3637
interface Props {
3738
maxValue: number
3839
currentValue: number
@@ -59,6 +60,8 @@ const props = withDefaults(defineProps<Props>(), {
5960
],
6061
})
6162
63+
const formatBytes = useFormatBytes()
64+
6265
const currentPhrase = ref('')
6366
const usedPhrases = ref(new Set<number>())
6467
let phraseInterval: NodeJS.Timeout | null = null

packages/ui/src/components/base/DropzoneFileInput.vue

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import { FolderUpIcon } from '@modrinth/assets'
5050
import { fileIsValid } from '@modrinth/utils'
5151
import { ref } from 'vue'
5252
53+
import { useFormatBytes } from '../../composables'
5354
import { injectNotificationManager } from '../../providers'
5455
5556
const { addNotification } = injectNotificationManager()
@@ -78,6 +79,8 @@ const props = withDefaults(
7879
},
7980
)
8081
82+
const formatBytes = useFormatBytes()
83+
8184
const files = ref<File[]>([])
8285
8386
function matchesAccept(file: File, accept?: string): boolean {
@@ -129,7 +132,7 @@ function addFiles(incoming: FileList, shouldNotReset = false) {
129132
alertOnInvalid: true,
130133
}
131134
132-
files.value = files.value.filter((file) => fileIsValid(file, validationOptions))
135+
files.value = files.value.filter((file) => fileIsValid(file, validationOptions, formatBytes))
133136
134137
if (files.value.length > 0) {
135138
emit('change', files.value)

0 commit comments

Comments
 (0)