From 02a77747229021b0ab6650412719c0fe0d0494c1 Mon Sep 17 00:00:00 2001 From: Mr_chank Date: Sat, 16 May 2026 00:58:26 +1000 Subject: [PATCH] fix: add download attribute to fix JAR files saving as ZIP in Chromium (#6065) * fix: add download attribute to fix JAR files saving as ZIP in Chromium - JAR files were downloading with a `.zip` extension in Chromium-based browsers (Chrome, Edge, Arc, Brave, Opera, Vivaldi) - Root cause: JAR files are ZIP archives internally, so Chromium sniffs the `Content-Type` as `application/zip` and overrides the filename extension when no `download` attribute is present - Fix: add `download=""` to all file download `` tags so the browser uses the original filename from the API * fix: add download attribute to remaining download links Missed in initial pass: changelog page button, versions overflow menu, settings/versions overflow menu. Also adds `download` prop to Button and OverflowMenu to support dropdown link items. Adds missing `getPrimaryFile` definition in changelog.vue. --------- Co-authored-by: Mr_chank <180248271+chank-op@users.noreply.github.com> Co-authored-by: Prospector <6166773+Prospector@users.noreply.github.com> --- .../frontend/src/pages/[type]/[id]/changelog.vue | 1 + .../src/pages/[type]/[id]/settings/versions.vue | 1 + .../src/pages/[type]/[id]/version/[version].vue | 2 ++ apps/frontend/src/pages/[type]/[id]/versions.vue | 2 ++ packages/ui/src/components/base/Button.vue | 5 +++++ packages/ui/src/components/base/OverflowMenu.vue | 2 ++ .../ui/src/components/version/VersionSummary.vue | 16 +++++++++++++--- 7 files changed, 26 insertions(+), 3 deletions(-) diff --git a/apps/frontend/src/pages/[type]/[id]/changelog.vue b/apps/frontend/src/pages/[type]/[id]/changelog.vue index e6974b6d1..cd85b5cac 100644 --- a/apps/frontend/src/pages/[type]/[id]/changelog.vue +++ b/apps/frontend/src/pages/[type]/[id]/changelog.vue @@ -57,6 +57,7 @@ { emit('onDownload') }, diff --git a/packages/ui/src/components/base/Button.vue b/packages/ui/src/components/base/Button.vue index 22f8b4cf5..48416b4f5 100644 --- a/packages/ui/src/components/base/Button.vue +++ b/packages/ui/src/components/base/Button.vue @@ -11,6 +11,10 @@ const props = defineProps({ type: Boolean, default: false, }, + download: { + type: String, + default: null, + }, action: { type: Function, default: null, @@ -106,6 +110,7 @@ const classes = computed(() => { class="btn" :class="classes" :href="disabled ? undefined : link" + :download="download || undefined" :target="external ? '_blank' : '_self'" @click=" (event) => { diff --git a/packages/ui/src/components/base/OverflowMenu.vue b/packages/ui/src/components/base/OverflowMenu.vue index f0949a3a9..92db08c3c 100644 --- a/packages/ui/src/components/base/OverflowMenu.vue +++ b/packages/ui/src/components/base/OverflowMenu.vue @@ -36,6 +36,7 @@ : undefined " :link="option.link ? option.link : undefined" + :download="option.download ? option.download : undefined" :external="option.external ? option.external : false" :disabled="option.disabled" @click=" @@ -76,6 +77,7 @@ interface Item extends BaseOption { icon?: Component action?: (event?: MouseEvent) => void link?: string + download?: string external?: boolean color?: | 'primary' diff --git a/packages/ui/src/components/version/VersionSummary.vue b/packages/ui/src/components/version/VersionSummary.vue index a14e0ac02..8e26a8ea1 100644 --- a/packages/ui/src/components/version/VersionSummary.vue +++ b/packages/ui/src/components/version/VersionSummary.vue @@ -12,7 +12,12 @@

-
+ @@ -42,12 +47,17 @@ const props = defineProps<{ decorateDownloadUrl?: (url: string) => string }>() +const primaryFile = computed( + () => props.version.files.find((x) => x.primary) || props.version.files[0], +) + const downloadUrl = computed(() => { - const primary: VersionFile = props.version.files.find((x) => x.primary) || props.version.files[0] - const raw = primary.url + const raw = primaryFile.value.url return props.decorateDownloadUrl ? props.decorateDownloadUrl(raw) : raw }) +const primaryFilename = computed(() => primaryFile.value.filename) + const emit = defineEmits<{ onDownload: [] onNavigate: [url: string]