mirror of
https://github.com/modrinth/code.git
synced 2026-08-30 11:36:05 +00:00
feat: implement opening project download modal in place in version page
This commit is contained in:
@@ -89,7 +89,7 @@ import {
|
||||
} from '@modrinth/ui'
|
||||
import type { DisplayProjectType } from '@modrinth/utils'
|
||||
import { useQuery } from '@tanstack/vue-query'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import { computed, nextTick, ref, watch } from 'vue'
|
||||
|
||||
import { navigateTo } from '#app'
|
||||
import { saveFeatureFlags } from '~/composables/featureFlags.ts'
|
||||
@@ -118,11 +118,13 @@ type NewModalRef = {
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
projectId: string
|
||||
projectId?: string
|
||||
downloadReason?: CdnDownloadReason
|
||||
useRouteHash?: boolean
|
||||
}>(),
|
||||
{
|
||||
downloadReason: 'standalone',
|
||||
useRouteHash: true,
|
||||
},
|
||||
)
|
||||
|
||||
@@ -140,19 +142,20 @@ const debug = useDebugLogger('DownloadModal')
|
||||
|
||||
const modal = ref<NewModalRef | null>(null)
|
||||
const modalOpen = ref(false)
|
||||
const showProjectId = ref<string | null>(null)
|
||||
const downloadProjectResetKey = ref(0)
|
||||
const projectDownloadSelection = ref<ProjectDownloadSelection>({
|
||||
currentGameVersion: null,
|
||||
currentPlatform: null,
|
||||
selectedVersion: null,
|
||||
selectedPrimaryFile: null,
|
||||
})
|
||||
const projectDownloadSelection = ref<ProjectDownloadSelection>(getDefaultProjectDownloadSelection())
|
||||
|
||||
const routeProjectId = computed(() => props.projectId)
|
||||
const routeProjectId = computed(() => showProjectId.value ?? props.projectId ?? null)
|
||||
|
||||
const { data: projectRaw, error: projectV2Error } = useQuery({
|
||||
const {
|
||||
data: projectRaw,
|
||||
error: projectV2Error,
|
||||
refetch: refetchProject,
|
||||
} = useQuery({
|
||||
queryKey: computed(() => ['project', 'v2', routeProjectId.value]),
|
||||
queryFn: () => client.labrinth.projects_v2.get(routeProjectId.value),
|
||||
queryFn: () => client.labrinth.projects_v2.get(routeProjectId.value!),
|
||||
enabled: computed(() => !!routeProjectId.value),
|
||||
staleTime: STALE_TIME,
|
||||
})
|
||||
|
||||
@@ -320,23 +323,33 @@ function onShow() {
|
||||
modalOpen.value = true
|
||||
debug('on-show fired')
|
||||
versionsEnabled.value = true
|
||||
navigateTo({ query: route.query, hash: '#download' }, { replace: true })
|
||||
if (props.useRouteHash && !showProjectId.value) {
|
||||
navigateTo({ query: route.query, hash: '#download' }, { replace: true })
|
||||
}
|
||||
}
|
||||
|
||||
function onHide() {
|
||||
const hadShowProjectId = !!showProjectId.value
|
||||
modalOpen.value = false
|
||||
navigateTo({ query: route.query, hash: '' }, { replace: true })
|
||||
showProjectId.value = null
|
||||
if (props.useRouteHash && !hadShowProjectId) {
|
||||
navigateTo({ query: route.query, hash: '' }, { replace: true })
|
||||
}
|
||||
}
|
||||
|
||||
function show(event?: MouseEvent) {
|
||||
async function show(event?: MouseEvent, projectId?: string): Promise<void> {
|
||||
if (!modal.value || modalOpen.value) return
|
||||
showProjectId.value = projectId ?? null
|
||||
await nextTick()
|
||||
if (!(await loadProjectForModal(!!projectId))) return
|
||||
modalOpen.value = true
|
||||
modal.value.show(event)
|
||||
}
|
||||
|
||||
function hide() {
|
||||
async function hide() {
|
||||
if (!modal.value || !modalOpen.value) return
|
||||
modal.value?.hide()
|
||||
await nextTick()
|
||||
downloadProjectResetKey.value += 1
|
||||
}
|
||||
|
||||
@@ -344,17 +357,43 @@ function onDownload() {
|
||||
emit('download')
|
||||
}
|
||||
|
||||
function getDefaultProjectDownloadSelection(): ProjectDownloadSelection {
|
||||
return {
|
||||
currentGameVersion: null,
|
||||
currentPlatform: null,
|
||||
selectedVersion: null,
|
||||
selectedPrimaryFile: null,
|
||||
}
|
||||
}
|
||||
|
||||
async function loadProjectForModal(forceRefetch: boolean) {
|
||||
if (!routeProjectId.value) return false
|
||||
if (!forceRefetch && projectRaw.value) return true
|
||||
|
||||
const { data } = await refetchProject()
|
||||
return !!data
|
||||
}
|
||||
|
||||
function openFromHash() {
|
||||
if (!modal.value || modalOpen.value || route.hash !== '#download') return
|
||||
if (
|
||||
!props.useRouteHash ||
|
||||
!modal.value ||
|
||||
modalOpen.value ||
|
||||
showProjectId.value ||
|
||||
route.hash !== '#download'
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
debug('hash #download watch fired, opening modal')
|
||||
show()
|
||||
}
|
||||
|
||||
if (
|
||||
route.hash === '#download' ||
|
||||
route.query.version !== undefined ||
|
||||
route.query.loader !== undefined
|
||||
props.useRouteHash &&
|
||||
(route.hash === '#download' ||
|
||||
route.query.version !== undefined ||
|
||||
route.query.loader !== undefined)
|
||||
) {
|
||||
debug('eager loadVersions from setup', {
|
||||
hash: route.hash,
|
||||
@@ -367,6 +406,10 @@ if (
|
||||
|
||||
watch(modal, openFromHash)
|
||||
watch(() => route.hash, openFromHash)
|
||||
watch(routeProjectId, () => {
|
||||
projectDownloadSelection.value = getDefaultProjectDownloadSelection()
|
||||
downloadProjectResetKey.value += 1
|
||||
})
|
||||
|
||||
defineExpose({ show, hide })
|
||||
</script>
|
||||
|
||||
@@ -80,6 +80,12 @@
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
<ProjectDownloadModal
|
||||
ref="dependencyDownloadModal"
|
||||
download-reason="dependency"
|
||||
:use-route-hash="false"
|
||||
@download="emit('onDownload')"
|
||||
/>
|
||||
<div class="flex flex-col">
|
||||
<nuxt-link
|
||||
class="mb-4 flex w-fit items-center gap-2 rounded-lg px-2 py-0.5 pl-0 text-link"
|
||||
@@ -364,14 +370,14 @@
|
||||
>
|
||||
<DownloadIcon />
|
||||
</a>
|
||||
<a
|
||||
<button
|
||||
v-else-if="dependency.project"
|
||||
v-tooltip="formatMessage(messages.downloadProject)"
|
||||
:href="`/project/${dependency.project.id}#download`"
|
||||
target="_blank"
|
||||
:aria-label="formatMessage(messages.downloadProject)"
|
||||
@click="openDependencyDownloadModal(dependency.project.id, $event)"
|
||||
>
|
||||
<DownloadIcon />
|
||||
</a>
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</template>
|
||||
</VersionPage>
|
||||
@@ -519,6 +525,7 @@ import { useMutation, useQuery, useQueryClient } from '@tanstack/vue-query'
|
||||
import { onServerPrefetch } from 'vue'
|
||||
|
||||
import CreateProjectVersionModal from '~/components/ui/create-project-version/CreateProjectVersionModal.vue'
|
||||
import ProjectDownloadModal from '~/components/ui/ProjectDownloadModal/index.vue'
|
||||
import { getSignInRouteObj } from '~/composables/auth.ts'
|
||||
import { projectQueryOptions, STALE_TIME } from '~/composables/queries/project'
|
||||
import { versionQueryOptions } from '~/composables/queries/version'
|
||||
@@ -774,6 +781,7 @@ useSeoMeta({
|
||||
const editModal = useTemplateRef('editModal')
|
||||
const confirmModal = useTemplateRef('confirmModal')
|
||||
const packageModal = useTemplateRef('packageModal')
|
||||
const dependencyDownloadModal = useTemplateRef('dependencyDownloadModal')
|
||||
|
||||
const packageLoaders = ref(['forge', 'fabric', 'quilt', 'neoforge'])
|
||||
const packageLoaderOptions = [
|
||||
@@ -796,6 +804,10 @@ function handleOpenEditVersionModal(versionId: string, projectId: string, stageI
|
||||
editModal.value?.openEditVersionModal(versionId, projectId, stageId)
|
||||
}
|
||||
|
||||
function openDependencyDownloadModal(projectId: string, event: MouseEvent) {
|
||||
dependencyDownloadModal.value?.show(event, projectId)
|
||||
}
|
||||
|
||||
const deleteVersionMutation = useMutation({
|
||||
mutationFn: () => client.labrinth.versions_v3.deleteVersion(version.value!.id),
|
||||
onSuccess: async () => {
|
||||
@@ -1065,7 +1077,11 @@ function getDependencyVersion(dependency: Labrinth.Versions.v3.Dependency) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return projectOnlyDependencyVersions.value?.[dependency.project_id]
|
||||
return (
|
||||
(Object.keys(projectOnlyDependencyVersions.value || {}).length === 1 &&
|
||||
projectOnlyDependencyVersions.value?.[dependency.project_id]) ||
|
||||
undefined
|
||||
)
|
||||
}
|
||||
|
||||
function getDependencyPrimaryFile(version?: Labrinth.Versions.v2.Version) {
|
||||
|
||||
Reference in New Issue
Block a user