Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ const modalConfirmUnpair = ref()
const modalConfirmReinstall = ref()

const props = defineProps<InstanceSettingsTabProps>()
const emit = defineEmits<{
unlinked: []
}>()

const loader = ref(props.instance.loader)
const gameVersion = ref(props.instance.game_version)
Expand Down Expand Up @@ -273,7 +276,7 @@ async function unpairProfile() {
modpackProject.value = null
modpackVersion.value = null
modpackVersions.value = null
modalConfirmUnpair.value.hide()
emit('unlinked')
}

async function repairModpack() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang="ts">
import { ConfirmModal } from '@modrinth/ui'
import { ref } from 'vue'
import { useTemplateRef } from 'vue'

import { hide_ads_window, show_ads_window } from '@/helpers/ads.js'
import { useTheming } from '@/store/theme.ts'
Expand Down Expand Up @@ -49,16 +49,16 @@ const props = defineProps({
})

const emit = defineEmits(['proceed'])
const modal = ref(null)
const modal = useTemplateRef('modal')

defineExpose({
show: () => {
hide_ads_window()
modal.value.show()
modal.value?.show()
},
hide: () => {
onModalHide()
modal.value.hide()
modal.value?.hide()
},
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,12 @@ import type { InstanceSettingsTabProps } from '../../../helpers/types'
const { formatMessage } = useVIntl()

const props = defineProps<InstanceSettingsTabProps>()
const emit = defineEmits<{
unlinked: []
}>()

const isMinecraftServer = ref(false)
const handleUnlinked = () => emit('unlinked')

watch(
() => props.instance,
Expand Down Expand Up @@ -121,7 +125,14 @@ defineExpose({ show })

<TabbedModal
:tabs="
tabs.map((tab) => ({ ...tab, props: { ...props, isMinecraftServer: isMinecraftServer } }))
tabs.map((tab) => ({
...tab,
props: {
...props,
isMinecraftServer,
onUnlinked: handleUnlinked,
},
}))
"
/>
</ModalWrapper>
Expand Down
61 changes: 36 additions & 25 deletions apps/app-frontend/src/pages/instance/Index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@
<div v-if="instance">
<div class="p-6 pr-2 pb-4" @contextmenu.prevent.stop="(event) => handleRightClick(event)">
<ExportModal ref="exportModal" :instance="instance" />
<InstanceSettingsModal ref="settingsModal" :instance="instance" :offline="offline" />
<InstanceSettingsModal
ref="settingsModal"
:instance="instance"
:offline="offline"
@unlinked="fetchInstance"
/>
<UpdateToPlayModal ref="updateToPlayModal" :instance="instance" />
<ContentPageHeader>
<template #icon>
Expand Down Expand Up @@ -55,27 +60,26 @@
</template>

<template v-else>
<ServerOnlinePlayers
v-if="playersOnline !== undefined"
:online="playersOnline"
:status-online="statusOnline"
hide-label
/>

<ServerRecentPlays :recent-plays="recentPlays ?? 0" hide-label />

<div
v-if="
(playersOnline !== undefined || recentPlays !== undefined) &&
(minecraftServer?.region || ping)
"
class="w-1.5 h-1.5 rounded-full bg-surface-5"
></div>
<template v-if="loadingServerPing">
<ServerOnlinePlayers
v-if="playersOnline !== undefined"
:online="playersOnline"
:status-online="statusOnline"
hide-label
/>
<ServerRecentPlays :recent-plays="recentPlays ?? 0" hide-label />
<div
v-if="
(playersOnline !== undefined || recentPlays !== undefined) &&
(minecraftServer?.region || ping)
"
class="w-1.5 h-1.5 rounded-full bg-surface-5"
></div>
<ServerPing v-if="ping" :ping="ping" />
</template>

<ServerRegion v-if="minecraftServer?.region" :region="minecraftServer?.region" />

<ServerPing v-if="ping" :ping="ping" />

<div
v-if="minecraftServer?.region || ping"
class="w-1.5 h-1.5 rounded-full bg-surface-5"
Expand Down Expand Up @@ -329,7 +333,7 @@ import { get_by_profile_path } from '@/helpers/process'
import { finish_install, get, get_full_path, kill, run } from '@/helpers/profile'
import type { GameInstance } from '@/helpers/types'
import { showProfileInFolder } from '@/helpers/utils.js'
import { get_server_status, getServerLatency } from '@/helpers/worlds'
import { get_server_status } from '@/helpers/worlds'
import { handleSevereError } from '@/store/error.js'
import { playServerProject } from '@/store/install.js'
import { useBreadcrumbs, useLoading } from '@/store/state'
Expand Down Expand Up @@ -370,13 +374,15 @@ const recentPlays = computed(
)
const playersOnline = ref<number | undefined>(undefined)
const ping = ref<number | undefined>(undefined)
const loadingServerPing = ref(false)

async function fetchInstance() {
isServerInstance.value = false
linkedProjectV3.value = undefined
modrinthVersions.value = []
ping.value = undefined
playersOnline.value = undefined
loadingServerPing.value = false

instance.value = await get(route.params.id as string).catch(handleError)

Expand Down Expand Up @@ -409,14 +415,19 @@ async function fetchInstance() {
function fetchDeferredData() {
const serverAddress = linkedProjectV3.value?.minecraft_java_server?.address
if (isServerInstance.value && serverAddress) {
Promise.all([get_server_status(serverAddress), getServerLatency(serverAddress)])
.then(([status, latency]) => {
ping.value = latency
get_server_status(serverAddress)
.then((status) => {
playersOnline.value = status.players?.online
ping.value = status.ping
})
.catch((error) => {
console.error(`Failed to fetch server status for ${serverAddress}:`, error)
})
.catch((err) => {
console.error(`Failed to ping server ${serverAddress}:`, err)
.finally(() => {
loadingServerPing.value = true
})
} else {
loadingServerPing.value = true
}

updatePlayState()
Expand Down
4 changes: 2 additions & 2 deletions apps/app-frontend/src/pages/project/Index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
:project-v3="projectV3"
class="project-sidebar-section"
/>
<ProjectSidebarTags :project="data" class="project-sidebar-section" />
<ProjectSidebarCreators
:organization="null"
:members="members"
Expand All @@ -34,7 +35,6 @@
link-target="_blank"
class="project-sidebar-section"
/>
<ProjectSidebarTags :project="data" class="project-sidebar-section" />
<ProjectSidebarDetails
:project="data"
:has-versions="versions.length > 0"
Expand Down Expand Up @@ -79,7 +79,7 @@
}}
</button>
</ButtonStyled>
<ButtonStyled size="large" circular type="transparent">
<ButtonStyled size="large" circular>
<button v-tooltip="'Add server to instance'" @click="handleAddServerToInstance">
<PlusIcon />
</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ const userOption = computed(() => ({
h('img', {
src: auth.value.user?.avatar_url,
alt: 'User Avatar',
class: 'h-5 w-5 rounded',
class: 'h-5 w-5 rounded-full',
}),
}),
)
Expand Down
11 changes: 11 additions & 0 deletions apps/frontend/src/composables/queries/version.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { AbstractModrinthClient } from '@modrinth/api-client'

import { STALE_TIME } from './project'

export const versionQueryOptions = {
v3: (versionId: string, client: AbstractModrinthClient) => ({
queryKey: ['version', 'v3', versionId] as const,
queryFn: () => client.labrinth.versions_v3.getVersion(versionId),
staleTime: STALE_TIME,
}),
}
9 changes: 9 additions & 0 deletions apps/frontend/src/locales/en-US/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -2132,6 +2132,12 @@
"project-type.datapack.singular": {
"message": "Data Pack"
},
"project-type.minecraft_java_server.plural": {
"message": "Servers"
},
"project-type.minecraft_java_server.singular": {
"message": "Server"
},
"project-type.mod.plural": {
"message": "Mods"
},
Expand Down Expand Up @@ -2990,6 +2996,9 @@
"settings.display.project-list-layouts.resourcepack": {
"message": "Resource Packs page"
},
"settings.display.project-list-layouts.server": {
"message": "Servers page"
},
"settings.display.project-list-layouts.shader": {
"message": "Shaders page"
},
Expand Down
71 changes: 47 additions & 24 deletions apps/frontend/src/pages/[type]/[id].vue
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,27 @@
"
>
<template #actions>
<ButtonStyled v-if="auth.user && currentMember" size="large" color="brand">
<ButtonStyled
v-if="auth.user && currentMember"
size="large"
color="brand"
class="lg:!hidden"
circular
>
<nuxt-link
v-tooltip="'Edit project'"
:to="`/${project.project_type}/${project.slug ? project.slug : project.id}/settings`"
class="!font-bold"
>
<SettingsIcon aria-hidden="true" />
</nuxt-link>
</ButtonStyled>
<ButtonStyled
v-if="auth.user && currentMember"
size="large"
color="brand"
class="max-lg:!hidden"
>
<nuxt-link
:to="`/${project.project_type}/${project.slug ? project.slug : project.id}/settings`"
class="!font-bold"
Expand Down Expand Up @@ -501,7 +521,11 @@
v-if="!isServerProject"
size="large"
circular
:color="route.name === 'type-id-version-version' ? `standard` : `brand`"
:color="
route.name === 'type-id-version-version' || (auth.user && currentMember)
? `standard`
: `brand`
"
>
<button
:aria-label="formatMessage(commonMessages.downloadButton)"
Expand All @@ -515,7 +539,11 @@
v-else
size="large"
circular
:color="route.name === 'type-id-version-version' ? `standard` : `brand`"
:color="
route.name === 'type-id-version-version' || (auth.user && currentMember)
? `standard`
: `brand`
"
>
<button aria-label="Play" class="flex sm:hidden" @click="handlePlayServerProject">
<PlayIcon aria-hidden="true" />
Expand Down Expand Up @@ -1070,6 +1098,7 @@ import NavTabs from '~/components/ui/NavTabs.vue'
import ProjectMemberHeader from '~/components/ui/ProjectMemberHeader.vue'
import { saveFeatureFlags } from '~/composables/featureFlags.ts'
import { STALE_TIME, STALE_TIME_LONG } from '~/composables/queries/project'
import { versionQueryOptions } from '~/composables/queries/version'
import { userCollectProject, userFollowProject } from '~/composables/user.js'
import { useModerationStore } from '~/store/moderation.ts'
import { reportProject } from '~/utils/report-helpers.ts'
Expand Down Expand Up @@ -1630,52 +1659,41 @@ const serverModpackVersionId = computed(() => {
})

const { data: serverModpackVersion, isPending: serverModpackVersionPending } = useQuery({
queryKey: computed(() => ['sidebar-modpack-version', serverModpackVersionId.value]),
queryKey: computed(() => ['version', 'v3', serverModpackVersionId.value]),
queryFn: () => client.labrinth.versions_v3.getVersion(serverModpackVersionId.value),
staleTime: STALE_TIME,
enabled: computed(() => !!serverModpackVersionId.value),
})

const serverModpackProjectId = computed(() => serverModpackVersion.value?.project_id ?? null)

const { data: serverModpackProject, isPending: serverModpackProjectPending } = useQuery({
queryKey: computed(() => ['sidebar-modpack-project', serverModpackProjectId.value]),
queryFn: () => client.labrinth.projects_v3.get(serverModpackProjectId.value),
staleTime: STALE_TIME,
enabled: computed(() => !!serverModpackProjectId.value),
})

const serverDataLoaded = computed(() => {
if (!projectV3.value) return false
if (serverModpackVersionId.value && serverModpackVersionPending.value) return false
if (serverModpackProjectId.value && serverModpackProjectPending.value) return false
return true
})

const serverRequiredContent = computed(() => {
if (!serverModpackProject.value) return null
const content = projectV3.value?.minecraft_java_server?.content
if (!content || content.kind !== 'modpack') return null
const primaryFile =
serverModpackVersion.value?.files?.find((f) => f.primary) ??
serverModpackVersion.value?.files?.[0]
return {
name: serverModpackProject.value.name,
name: content.project_name ?? '',
versionNumber: serverModpackVersion.value?.version_number ?? '',
icon: serverModpackProject.value.icon_url,
icon: content.project_icon,
onclickName:
serverModpackProject.value.id !== projectId.value
? () => navigateTo(`/modpack/${serverModpackProject.value.slug}`)
content.project_id && content.project_id !== projectId.value
? () => navigateTo(`/project/${content.project_id}`)
: undefined,
onclickVersion:
serverModpackProject.value.id !== projectId.value
content.project_id && content.project_id !== projectId.value
? () =>
navigateTo(
`/modpack/${serverModpackProject.value.slug}/version/${serverModpackVersion.value?.id}`,
)
navigateTo(`/project/${content.project_id}/version/${serverModpackVersion.value?.id}`)
: undefined,
onclickDownload: primaryFile?.url
? () => navigateTo(primaryFile.url, { external: true })
: undefined,
showCustomModpackTooltip: serverModpackProject.value.id === projectId.value,
showCustomModpackTooltip: content.project_id === projectId.value,
}
})

Expand Down Expand Up @@ -1710,6 +1728,11 @@ const serverModpackLoaders = computed(() => {
return serverModpackVersion.value.mrpack_loaders ?? []
})

watch(serverModpackVersionId, (versionId) => {
if (!versionId) return
queryClient.prefetchQuery(versionQueryOptions.v3(versionId, client))
})

// Members
const { data: allMembersRaw, error: _membersError } = useQuery({
queryKey: computed(() => ['project', projectId.value, 'members']),
Expand Down
Loading