From d4a6034e2b9f346170e020d72cd7015a2eaf24a0 Mon Sep 17 00:00:00 2001 From: "Calum H. (IMB11)" Date: Thu, 30 Oct 2025 15:19:33 +0000 Subject: [PATCH 1/3] fix: firefox backup download issues --- .../src/components/ui/servers/BackupItem.vue | 74 ++++++++++++++--- .../composables/servers/modules/backups.ts | 83 +++++++++++++++++++ .../src/pages/servers/manage/[id]/backups.vue | 1 + 3 files changed, 147 insertions(+), 11 deletions(-) diff --git a/apps/frontend/src/components/ui/servers/BackupItem.vue b/apps/frontend/src/components/ui/servers/BackupItem.vue index 6e910066ed..c4c921594c 100644 --- a/apps/frontend/src/components/ui/servers/BackupItem.vue +++ b/apps/frontend/src/components/ui/servers/BackupItem.vue @@ -13,14 +13,23 @@ import { TrashIcon, XIcon, } from '@modrinth/assets' -import { ButtonStyled, commonMessages, OverflowMenu, ProgressBar } from '@modrinth/ui' +import { + ButtonStyled, + commonMessages, + injectNotificationManager, + OverflowMenu, + ProgressBar, +} from '@modrinth/ui' import type { Backup } from '@modrinth/utils' import { defineMessages, useVIntl } from '@vintl/vintl' import dayjs from 'dayjs' -import { computed } from 'vue' +import { computed, ref } from 'vue' + +import type { ModrinthServer } from '~/composables/servers/modrinth-servers.ts' const flags = useFeatureFlags() const { formatMessage } = useVIntl() +const { addNotification } = injectNotificationManager() const emit = defineEmits<{ (e: 'download' | 'rename' | 'restore' | 'lock' | 'retry'): void @@ -33,11 +42,13 @@ const props = withDefaults( preview?: boolean kyrosUrl?: string jwt?: string + server?: ModrinthServer }>(), { preview: false, kyrosUrl: undefined, jwt: undefined, + server: undefined, }, ) @@ -124,7 +135,44 @@ const messages = defineMessages({ id: 'servers.backups.item.retry', defaultMessage: 'Retry', }, + downloadingBackup: { + id: 'servers.backups.item.downloading-backup', + defaultMessage: 'Downloading backup...', + }, }) + +const downloadingState = ref<{ progress: number; state: string } | undefined>(undefined) + +const downloading = computed(() => downloadingState.value) + +const handleDownload = async () => { + if (!props.server?.backups || downloading.value) { + return + } + + downloadingState.value = { progress: 0, state: 'ongoing' } + + try { + const download = props.server.backups.downloadBackup(props.backup.id, props.backup.name) + + download.onProgress((p) => { + downloadingState.value = { progress: p.progress, state: 'ongoing' } + }) + + await download.promise + + emit('download') + } catch (error) { + console.error('Failed to download backup:', error) + addNotification({ + type: 'error', + title: 'Download failed', + text: error instanceof Error ? error.message : 'Failed to download backup', + }) + } finally { + downloadingState.value = undefined + } +}