mirror of
https://github.com/modrinth/code.git
synced 2026-08-30 11:36:05 +00:00
refactor: move additional files into download dependencies section
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<div v-if="dependencyRows.length > 0" class="flex flex-col gap-1">
|
||||
<div v-if="downloadRows.length > 0" class="flex flex-col gap-1">
|
||||
<div
|
||||
v-if="showTitle || downloadableDependencyFiles.length > 0"
|
||||
class="flex flex-wrap items-center justify-between gap-2"
|
||||
>
|
||||
<h3 v-if="showTitle" class="m-0 text-base font-semibold text-contrast">
|
||||
{{ formatMessage(messages.dependenciesTitle) }}
|
||||
{{ sectionTitle }}
|
||||
</h3>
|
||||
<ButtonStyled v-if="downloadableDependencyFiles.length > 0" type="transparent">
|
||||
<button :disabled="downloadingDependencies" @click="downloadAllDependencies">
|
||||
@@ -23,7 +23,7 @@
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<DownloadDependency
|
||||
v-for="dependency in dependencyRows"
|
||||
v-for="dependency in downloadRows"
|
||||
:key="dependency.key"
|
||||
:dependency="dependency"
|
||||
@download="emit('download')"
|
||||
@@ -34,11 +34,12 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Labrinth } from '@modrinth/api-client'
|
||||
import { DownloadIcon, SpinnerIcon } from '@modrinth/assets'
|
||||
import { DownloadIcon, FileIcon, SpinnerIcon } from '@modrinth/assets'
|
||||
import {
|
||||
ButtonStyled,
|
||||
type CdnDownloadReason,
|
||||
defineMessages,
|
||||
fileTypeMessages,
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
useVIntl,
|
||||
@@ -46,7 +47,7 @@ import {
|
||||
import type { DisplayProjectType } from '@modrinth/utils'
|
||||
import { useQuery } from '@tanstack/vue-query'
|
||||
import JSZip from 'jszip'
|
||||
import { computed, ref } from 'vue'
|
||||
import { type Component, computed, ref } from 'vue'
|
||||
|
||||
import DownloadDependency from './DownloadDependency.vue'
|
||||
|
||||
@@ -65,6 +66,7 @@ interface DownloadDependencyRow {
|
||||
key: string
|
||||
name: string
|
||||
icon?: string
|
||||
fallbackIcon?: Component
|
||||
projectHref?: string
|
||||
downloadHref?: string
|
||||
filename?: string
|
||||
@@ -87,6 +89,7 @@ const props = withDefaults(
|
||||
currentGameVersion?: string | null
|
||||
currentPlatform?: string | null
|
||||
downloadReason?: CdnDownloadReason
|
||||
additionalFiles?: Labrinth.Versions.v3.VersionFile[]
|
||||
showTitle?: boolean
|
||||
}>(),
|
||||
{
|
||||
@@ -96,6 +99,7 @@ const props = withDefaults(
|
||||
currentGameVersion: null,
|
||||
currentPlatform: null,
|
||||
downloadReason: 'standalone',
|
||||
additionalFiles: () => [],
|
||||
showTitle: true,
|
||||
},
|
||||
)
|
||||
@@ -258,8 +262,34 @@ const dependencyRows = computed<DownloadDependencyRow[]>(
|
||||
() => props.dependencies || resolvedDependencyRows.value,
|
||||
)
|
||||
|
||||
const additionalFileRows = computed<DownloadDependencyRow[]>(() =>
|
||||
props.additionalFiles.map((file) => ({
|
||||
key: `additional-file-${additionalFileKey(file)}`,
|
||||
name: file.filename,
|
||||
fallbackIcon: FileIcon,
|
||||
downloadHref: getDownloadUrl(file.url),
|
||||
filename: file.filename,
|
||||
typeLabel: fileTypeLabel(file.file_type),
|
||||
unavailableTooltip: formatMessage(messages.unavailableFile),
|
||||
dependencies: [],
|
||||
})),
|
||||
)
|
||||
|
||||
const downloadRows = computed<DownloadDependencyRow[]>(() => [
|
||||
...dependencyRows.value,
|
||||
...additionalFileRows.value,
|
||||
])
|
||||
|
||||
const sectionTitle = computed(() =>
|
||||
formatMessage(
|
||||
dependencyRows.value.length > 0
|
||||
? messages.dependenciesTitle
|
||||
: messages.additionalFilesTitle,
|
||||
),
|
||||
)
|
||||
|
||||
const downloadableDependencyFiles = computed<DownloadableDependencyFile[]>(() =>
|
||||
collectDownloadableDependencyFiles(dependencyRows.value),
|
||||
collectDownloadableDependencyFiles(downloadRows.value),
|
||||
)
|
||||
|
||||
const dependencyZipFilename = computed(
|
||||
@@ -336,6 +366,14 @@ function getDownloadUrl(url: string) {
|
||||
})
|
||||
}
|
||||
|
||||
function fileTypeLabel(type?: Labrinth.Versions.v3.FileType | null) {
|
||||
return formatMessage(fileTypeMessages[type ?? 'unknown'] ?? fileTypeMessages.unknown)
|
||||
}
|
||||
|
||||
function additionalFileKey(file: Labrinth.Versions.v3.VersionFile) {
|
||||
return file.hashes?.sha1 ?? file.filename
|
||||
}
|
||||
|
||||
function collectDownloadableDependencyFiles(
|
||||
rows: DownloadDependencyRow[],
|
||||
seenHrefs = new Set<string>(),
|
||||
@@ -458,6 +496,10 @@ const messages = defineMessages({
|
||||
id: 'project.download.dependencies-title',
|
||||
defaultMessage: 'Dependencies',
|
||||
},
|
||||
additionalFilesTitle: {
|
||||
id: 'project.download.additional-files-title',
|
||||
defaultMessage: 'Additional files',
|
||||
},
|
||||
downloadAllDependencies: {
|
||||
id: 'project.download.dependencies-download-all',
|
||||
defaultMessage: 'Download all',
|
||||
@@ -502,5 +544,9 @@ const messages = defineMessages({
|
||||
id: 'project.download.dependency-unavailable',
|
||||
defaultMessage: 'This dependency cannot be downloaded',
|
||||
},
|
||||
unavailableFile: {
|
||||
id: 'project.download.file-unavailable',
|
||||
defaultMessage: 'This file cannot be downloaded',
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -15,7 +15,11 @@
|
||||
v-else
|
||||
class="flex size-4 flex-shrink-0 items-center justify-center rounded-lg border border-solid border-surface-5 text-secondary"
|
||||
>
|
||||
<PackageIcon aria-hidden="true" class="size-5" />
|
||||
<component
|
||||
:is="dependency.fallbackIcon ?? PackageIcon"
|
||||
aria-hidden="true"
|
||||
class="size-5"
|
||||
/>
|
||||
</span>
|
||||
<a
|
||||
v-if="dependency.projectHref"
|
||||
@@ -79,7 +83,7 @@
|
||||
<script setup lang="ts">
|
||||
import { DownloadIcon, PackageIcon } from '@modrinth/assets'
|
||||
import { Avatar, ButtonStyled, TagItem, truncatedTooltip } from '@modrinth/ui'
|
||||
import { ref } from 'vue'
|
||||
import { type Component, ref } from 'vue'
|
||||
|
||||
defineOptions({
|
||||
name: 'DownloadDependency',
|
||||
@@ -89,6 +93,7 @@ interface DownloadDependencyRow {
|
||||
key: string
|
||||
name: string
|
||||
icon?: string
|
||||
fallbackIcon?: Component
|
||||
projectHref?: string
|
||||
downloadHref?: string
|
||||
filename?: string
|
||||
|
||||
@@ -34,49 +34,9 @@
|
||||
:current-game-version="currentGameVersion"
|
||||
:current-platform="currentPlatform"
|
||||
:download-reason="downloadReason"
|
||||
:additional-files="additionalFiles"
|
||||
@download="onDownload"
|
||||
/>
|
||||
<div v-if="additionalFiles.length > 0" class="flex flex-col gap-2">
|
||||
<h3 class="m-0 text-base font-semibold text-contrast">
|
||||
{{ formatMessage(messages.additionalFilesTitle) }}
|
||||
</h3>
|
||||
<div class="flex flex-col gap-2">
|
||||
<div
|
||||
v-for="file in additionalFiles"
|
||||
:key="additionalFileKey(file)"
|
||||
class="grid min-h-10 grid-cols-[minmax(0,1fr)_min-content] items-center gap-3 rounded-xl bg-button-bg py-0 pl-3.5 pr-2 text-primary"
|
||||
>
|
||||
<span class="flex min-w-0 items-center gap-3">
|
||||
<FileIcon aria-hidden="true" class="size-5 flex-shrink-0 text-secondary" />
|
||||
<span
|
||||
:ref="(element) => setAdditionalFileNameRef(file, element)"
|
||||
v-tooltip="
|
||||
truncatedTooltip(additionalFileNameRefs[additionalFileKey(file)], file.filename)
|
||||
"
|
||||
class="min-w-0 truncate text-base font-semibold text-contrast"
|
||||
>
|
||||
{{ file.filename }}
|
||||
</span>
|
||||
<TagItem
|
||||
class="shrink-0 border !border-solid border-surface-5 !px-3 !py-1 text-base"
|
||||
>
|
||||
{{ fileTypeLabel(file.file_type) }}
|
||||
</TagItem>
|
||||
</span>
|
||||
<ButtonStyled circular type="transparent">
|
||||
<a
|
||||
v-tooltip="'Download'"
|
||||
:href="getDownloadUrl(file.url)"
|
||||
:download="file.filename"
|
||||
:aria-label="`Download ${file.filename}`"
|
||||
@click="onDownload"
|
||||
>
|
||||
<DownloadIcon aria-hidden="true" class="size-6 text-secondary" />
|
||||
</a>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ServersPromo
|
||||
v-if="flags.showProjectPageDownloadModalServersPromo"
|
||||
@@ -95,24 +55,20 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Labrinth } from '@modrinth/api-client'
|
||||
import { DownloadIcon, FileIcon } from '@modrinth/assets'
|
||||
import {
|
||||
Avatar,
|
||||
ButtonStyled,
|
||||
type CdnDownloadReason,
|
||||
defineMessages,
|
||||
fileTypeMessages,
|
||||
injectModrinthClient,
|
||||
NewModal,
|
||||
ServersPromo,
|
||||
TagItem,
|
||||
truncatedTooltip,
|
||||
useDebugLogger,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import type { DisplayProjectType } from '@modrinth/utils'
|
||||
import { useQuery } from '@tanstack/vue-query'
|
||||
import { type ComponentPublicInstance, computed, nextTick, onUnmounted, ref, watch } from 'vue'
|
||||
import { computed, nextTick, onUnmounted, ref, watch } from 'vue'
|
||||
|
||||
import { navigateTo } from '#app'
|
||||
import { saveFeatureFlags } from '~/composables/featureFlags.ts'
|
||||
@@ -173,13 +129,11 @@ const route = useRoute()
|
||||
const flags = useFeatureFlags()
|
||||
const tags = useGeneratedState()
|
||||
const client = injectModrinthClient()
|
||||
const { createProjectDownloadUrl } = useCdnDownloadContext()
|
||||
const { formatMessage } = useVIntl()
|
||||
const debug = useDebugLogger('DownloadModal')
|
||||
|
||||
const modal = ref<NewModalRef | null>(null)
|
||||
const downloadTitleRef = ref<HTMLElement | null>(null)
|
||||
const additionalFileNameRefs = ref<Record<string, HTMLElement | null>>({})
|
||||
const modalOpen = ref(false)
|
||||
const showProjectId = ref<string | null>(null)
|
||||
const showOptions = ref<ResolvedProjectDownloadModalShowOptions>(getDefaultShowOptions())
|
||||
@@ -285,28 +239,8 @@ const messages = defineMessages({
|
||||
id: 'project.download.title',
|
||||
defaultMessage: 'Download {title}',
|
||||
},
|
||||
additionalFilesTitle: {
|
||||
id: 'project.download.additional-files-title',
|
||||
defaultMessage: 'Additional files',
|
||||
},
|
||||
})
|
||||
|
||||
function fileTypeLabel(type?: Labrinth.Versions.v3.FileType | null) {
|
||||
return formatMessage(fileTypeMessages[type ?? 'unknown'] ?? fileTypeMessages.unknown)
|
||||
}
|
||||
|
||||
function additionalFileKey(file: Labrinth.Versions.v3.VersionFile) {
|
||||
return file.hashes?.sha1 ?? file.filename
|
||||
}
|
||||
|
||||
function setAdditionalFileNameRef(
|
||||
file: Labrinth.Versions.v3.VersionFile,
|
||||
element: Element | ComponentPublicInstance | null,
|
||||
) {
|
||||
additionalFileNameRefs.value[additionalFileKey(file)] =
|
||||
element instanceof HTMLElement ? element : null
|
||||
}
|
||||
|
||||
function getProjectTypeForUrl(
|
||||
type: Labrinth.Projects.v2.ProjectType,
|
||||
loaders: string[],
|
||||
@@ -326,14 +260,6 @@ function getProjectTypeForUrl(
|
||||
return 'mod'
|
||||
}
|
||||
|
||||
function getDownloadUrl(url: string) {
|
||||
return createProjectDownloadUrl(url, {
|
||||
reason: props.downloadReason,
|
||||
gameVersion: currentGameVersion.value ?? undefined,
|
||||
loader: currentPlatform.value ?? undefined,
|
||||
})
|
||||
}
|
||||
|
||||
function updateDownloadQuery({
|
||||
gameVersion,
|
||||
platform,
|
||||
|
||||
Reference in New Issue
Block a user