diff --git a/apps/app-frontend/src/App.vue b/apps/app-frontend/src/App.vue index 9e12ac691d..291c45cc05 100644 --- a/apps/app-frontend/src/App.vue +++ b/apps/app-frontend/src/App.vue @@ -51,9 +51,10 @@ import { providePageContext, providePopupNotificationManager, useDebugLogger, + useFormatBytes, useVIntl, } from '@modrinth/ui' -import { formatBytes, renderString } from '@modrinth/utils' +import { renderString } from '@modrinth/utils' import { useQuery, useQueryClient } from '@tanstack/vue-query' import { getVersion } from '@tauri-apps/api/app' import { invoke } from '@tauri-apps/api/core' @@ -261,6 +262,8 @@ onUnmounted(async () => { }) const { formatMessage } = useVIntl() +const formatBytes = useFormatBytes() + const messages = defineMessages({ updateInstalledToastTitle: { id: 'app.update.complete-toast.title', diff --git a/apps/app-frontend/src/pages/project/Version.vue b/apps/app-frontend/src/pages/project/Version.vue index d405bd256a..655e88cb04 100644 --- a/apps/app-frontend/src/pages/project/Version.vue +++ b/apps/app-frontend/src/pages/project/Version.vue @@ -176,9 +176,10 @@ import { ButtonStyled, Card, CopyCode, + useFormatBytes, useFormatDateTime, } from '@modrinth/ui' -import { formatBytes, renderString } from '@modrinth/utils' +import { renderString } from '@modrinth/utils' import { computed, ref, watch } from 'vue' import { useRoute } from 'vue-router' @@ -191,6 +192,7 @@ const formatDateTime = useFormatDateTime({ timeStyle: 'short', dateStyle: 'long', }) +const formatBytes = useFormatBytes() const breadcrumbs = useBreadcrumbs() diff --git a/apps/frontend/src/components/ui/FileInput.vue b/apps/frontend/src/components/ui/FileInput.vue index 6ff1605ee0..6cf3c97ee7 100644 --- a/apps/frontend/src/components/ui/FileInput.vue +++ b/apps/frontend/src/components/ui/FileInput.vue @@ -17,74 +17,60 @@ - diff --git a/apps/frontend/src/components/ui/moderation/ModerationTechRevCard.vue b/apps/frontend/src/components/ui/moderation/ModerationTechRevCard.vue index a7287bb475..e80906a9c1 100644 --- a/apps/frontend/src/components/ui/moderation/ModerationTechRevCard.vue +++ b/apps/frontend/src/components/ui/moderation/ModerationTechRevCard.vue @@ -28,6 +28,7 @@ import { injectNotificationManager, OverflowMenu, type OverflowMenuOption, + useFormatBytes, useFormatDateTime, } from '@modrinth/ui' import { NavTabs } from '@modrinth/ui' @@ -56,6 +57,7 @@ const formatDateTimeUtc = useFormatDateTime({ timeZoneName: 'short', timeZone: 'UTC', }) +const formatBytes = useFormatBytes() type FlattenedFileReport = Labrinth.TechReview.Internal.FileReport & { id: string @@ -362,12 +364,6 @@ const formattedDate = computed(() => { return `${diffDays} days ago` }) -function formatFileSize(bytes: number): string { - if (bytes < 1024) return `${bytes} B` - if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(2)} KiB` - return `${(bytes / (1024 * 1024)).toFixed(2)} MiB` -} - function viewFileFlags(file: FlattenedFileReport) { selectedFileId.value = file.id currentTab.value = 'File' @@ -851,7 +847,7 @@ const reviewSummaryPreview = computed(() => { const fileVerdict = fileUnsafe > 0 ? 'Unsafe' : 'Safe' markdown += `### ${fileData.fileName}\n` - markdown += `> ${formatFileSize(fileData.fileSize)} • ${fileData.decisions.length} issues • Max severity: ${fileData.maxSeverity} • **Verdict:** ${fileVerdict}\n\n` + markdown += `> ${formatBytes(fileData.fileSize)} • ${fileData.decisions.length} issues • Max severity: ${fileData.maxSeverity} • **Verdict:** ${fileVerdict}\n\n` markdown += `
\nIssues (${fileSafe} safe, ${fileUnsafe} unsafe)\n\n` markdown += `| Class | Issue Type | Severity | Decision |\n` markdown += `|-------|------------|----------|----------|\n` @@ -1150,7 +1146,7 @@ async function handleSubmitReview(verdict: 'safe' | 'unsafe') {
{{ - formatFileSize(file.file_size) + formatBytes(file.file_size) }}
{ - const { maxSize, alertOnInvalid } = validationOptions - if (maxSize !== null && maxSize !== undefined && file.size > maxSize) { - if (alertOnInvalid) { - alert(`File ${file.name} is too big! Must be less than ${formatBytes(maxSize)}`) - } - return false - } - - return true -} - -export const acceptFileFromProjectType = (projectType) => { - switch (projectType) { - case 'mod': - return '.jar,.zip,.litemod,application/java-archive,application/x-java-archive,application/zip' - case 'plugin': - return '.jar,.zip,application/java-archive,application/x-java-archive,application/zip' - case 'resourcepack': - return '.zip,application/zip' - case 'shader': - return '.zip,application/zip' - case 'datapack': - return '.zip,application/zip' - case 'modpack': - return '.mrpack,application/x-modrinth-modpack+zip,application/zip' - default: - return '*' - } -} diff --git a/apps/frontend/src/pages/[type]/[id]/settings/index.vue b/apps/frontend/src/pages/[type]/[id]/settings/index.vue index b73efe46a6..a96fe4bad4 100644 --- a/apps/frontend/src/pages/[type]/[id]/settings/index.vue +++ b/apps/frontend/src/pages/[type]/[id]/settings/index.vue @@ -146,7 +146,11 @@ const input = e.target if (input.files?.length) { if ( - fileIsValid(input.files[0], { maxSize: 524288000, alertOnInvalid: true }) + fileIsValid( + input.files[0], + { maxSize: 524288000, alertOnInvalid: true }, + formatBytes, + ) ) showBannerPreview(Array.from(input.files)) } @@ -379,6 +383,7 @@ import { StyledInput, Toggle, UnsavedChangesPopup, + useFormatBytes, usePageLeaveSafety, } from '@modrinth/ui' import { fileIsValid, formatProjectStatus, formatProjectType } from '@modrinth/utils' @@ -405,6 +410,8 @@ const flags = useFeatureFlags() const tags = useGeneratedState() const router = useNativeRouter() +const formatBytes = useFormatBytes() + const name = ref(project.value.title) const slug = ref(project.value.slug) const summary = ref(project.value.description) diff --git a/apps/frontend/src/pages/[type]/[id]/version/[version].vue b/apps/frontend/src/pages/[type]/[id]/version/[version].vue index ff6decdfc8..de0f0b75bc 100644 --- a/apps/frontend/src/pages/[type]/[id]/version/[version].vue +++ b/apps/frontend/src/pages/[type]/[id]/version/[version].vue @@ -436,9 +436,10 @@ import { injectProjectPageContext, MultiSelect, StyledInput, + useFormatBytes, useFormatDateTime, } from '@modrinth/ui' -import { formatBytes, renderHighlightedString } from '@modrinth/utils' +import { renderHighlightedString } from '@modrinth/utils' import Breadcrumbs from '~/components/ui/Breadcrumbs.vue' import CreateProjectVersionModal from '~/components/ui/create-project-version/CreateProjectVersionModal.vue' @@ -466,6 +467,7 @@ const formatDateTime = useFormatDateTime({ dateStyle: 'long', }) const formatDate = useFormatDateTime({ dateStyle: 'medium' }) +const formatBytes = useFormatBytes() // Helper for accessing nuxt app $formatVersion const formatVersionDisplay = (versions: string[]) => (data as any).$formatVersion(versions) diff --git a/apps/frontend/src/pages/admin/file_lookup.vue b/apps/frontend/src/pages/admin/file_lookup.vue index 9bbae53cce..86f9841c87 100644 --- a/apps/frontend/src/pages/admin/file_lookup.vue +++ b/apps/frontend/src/pages/admin/file_lookup.vue @@ -81,11 +81,19 @@