mirror of
https://github.com/modrinth/code.git
synced 2026-08-31 12:05:53 +00:00
feat: reshuffle layout for worlds
This commit is contained in:
@@ -18,46 +18,28 @@
|
||||
<SettingsIcon />
|
||||
Configuring server...
|
||||
</div>
|
||||
<div v-else class="flex flex-wrap items-center gap-2">
|
||||
<div v-if="props.server?.loader" class="flex items-center gap-2 font-medium">
|
||||
<LoaderIcon :loader="props.server.loader" class="flex shrink-0 [&&]:size-5" />
|
||||
{{ formatLoaderLabel(props.server.loader) }} {{ props.server.mc_version }}
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="
|
||||
props.server?.loader &&
|
||||
props.server?.net?.domain &&
|
||||
!userPreferences.hideSubdomainLabel
|
||||
"
|
||||
class="h-1.5 w-1.5 rounded-full bg-surface-5"
|
||||
/>
|
||||
|
||||
<div
|
||||
v-if="props.server?.net?.domain && !userPreferences.hideSubdomainLabel"
|
||||
v-tooltip="'Copy server address'"
|
||||
class="flex cursor-pointer items-center gap-2 font-medium hover:underline text-nowrap"
|
||||
@click="copyServerAddress"
|
||||
>
|
||||
<LinkIcon class="flex size-5 shrink-0" />
|
||||
{{ props.server.net.domain }}.modrinth.gg
|
||||
</div>
|
||||
|
||||
<div v-if="showUptime" class="h-1.5 w-1.5 rounded-full bg-surface-5" />
|
||||
|
||||
<div v-if="showUptime" class="flex items-center gap-2 font-medium">
|
||||
<TimerIcon class="flex size-5 shrink-0" />
|
||||
{{ formattedUptime }}
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="showProject && (props.server?.loader || props.server?.net?.domain || showUptime)"
|
||||
class="h-1.5 w-1.5 rounded-full bg-surface-5"
|
||||
/>
|
||||
|
||||
<div v-else class="flex min-w-0 flex-wrap items-center gap-2">
|
||||
<template v-for="(item, index) in headerStats" :key="item.id">
|
||||
<div v-if="index > 0" class="h-1.5 w-1.5 rounded-full bg-surface-5" />
|
||||
<button
|
||||
v-if="item.copyable"
|
||||
v-tooltip="'Copy server address'"
|
||||
class="m-0 flex min-w-0 cursor-pointer items-center gap-2 border-0 bg-transparent p-0 font-medium text-secondary hover:underline text-nowrap"
|
||||
type="button"
|
||||
@click="copyServerAddress"
|
||||
>
|
||||
<component :is="item.icon" class="flex size-5 shrink-0" />
|
||||
<span class="truncate">{{ item.label }}</span>
|
||||
</button>
|
||||
<div v-else class="flex min-w-0 items-center gap-2 font-medium text-secondary text-nowrap">
|
||||
<component :is="item.icon" class="flex size-5 shrink-0" />
|
||||
<span class="truncate">{{ item.label }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<div v-if="showProject && headerStats.length > 0" class="h-1.5 w-1.5 rounded-full bg-surface-5" />
|
||||
<div
|
||||
v-if="showProject"
|
||||
class="flex items-center gap-1.5 font-medium text-primary text-nowrap"
|
||||
class="flex min-w-0 items-center gap-1.5 font-medium text-primary text-nowrap"
|
||||
>
|
||||
Linked to
|
||||
<Avatar
|
||||
@@ -81,8 +63,9 @@
|
||||
<script setup lang="ts">
|
||||
import type { Archon } from '@modrinth/api-client'
|
||||
import { NuxtModrinthClient } from '@modrinth/api-client'
|
||||
import { LinkIcon, SettingsIcon, TimerIcon } from '@modrinth/assets'
|
||||
import { GlobeIcon, LinkIcon, SettingsIcon, TimerIcon } from '@modrinth/assets'
|
||||
import { useStorage } from '@vueuse/core'
|
||||
import type { Component } from 'vue'
|
||||
import { computed } from 'vue'
|
||||
|
||||
import { AutoLink, Avatar, ContentPageHeader, ServerIcon } from '#ui/components'
|
||||
@@ -102,12 +85,20 @@ type ServerProjectSummary = {
|
||||
icon_url?: string | null
|
||||
}
|
||||
|
||||
type HeaderStat = {
|
||||
id: string
|
||||
label: string
|
||||
icon: Component
|
||||
copyable?: boolean
|
||||
}
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
server: Archon.Servers.v0.Server | null | undefined
|
||||
serverImage?: string | null
|
||||
serverProject?: ServerProjectSummary | null
|
||||
serverProjectLink?: string
|
||||
activeWorldName?: string | null
|
||||
uptimeSeconds?: number
|
||||
showUptime?: boolean
|
||||
backHref?: string
|
||||
@@ -118,6 +109,7 @@ const props = withDefaults(
|
||||
serverImage: null,
|
||||
serverProject: null,
|
||||
serverProjectLink: '',
|
||||
activeWorldName: null,
|
||||
uptimeSeconds: 0,
|
||||
showUptime: true,
|
||||
backHref: '/hosting/manage',
|
||||
@@ -158,6 +150,57 @@ const formattedUptime = computed(() => {
|
||||
return formatted.trim()
|
||||
})
|
||||
|
||||
const serverAddress = computed(() => {
|
||||
const domain = props.server?.net?.domain
|
||||
if (domain) return `${domain}.modrinth.gg`
|
||||
|
||||
const ip = props.server?.net?.ip
|
||||
if (!ip) return null
|
||||
const port = props.server?.net?.port
|
||||
return port ? `${ip}:${port}` : ip
|
||||
})
|
||||
|
||||
const showAddress = computed(
|
||||
() => !!serverAddress.value && (!props.server?.net?.domain || !userPreferences.value.hideSubdomainLabel),
|
||||
)
|
||||
|
||||
const headerStats = computed<HeaderStat[]>(() => {
|
||||
const stats: HeaderStat[] = []
|
||||
const worldName = props.activeWorldName
|
||||
if (worldName) {
|
||||
stats.push({
|
||||
id: 'world',
|
||||
label: worldName,
|
||||
icon: GlobeIcon,
|
||||
})
|
||||
}
|
||||
if (props.server?.loader) {
|
||||
stats.push({
|
||||
id: 'loader',
|
||||
label: props.server.mc_version
|
||||
? `${formatLoaderLabel(props.server.loader)} ${props.server.mc_version}`
|
||||
: formatLoaderLabel(props.server.loader),
|
||||
icon: LoaderIcon,
|
||||
})
|
||||
}
|
||||
if (showAddress.value && serverAddress.value) {
|
||||
stats.push({
|
||||
id: 'address',
|
||||
label: serverAddress.value,
|
||||
icon: LinkIcon,
|
||||
copyable: true,
|
||||
})
|
||||
}
|
||||
if (showUptime.value) {
|
||||
stats.push({
|
||||
id: 'uptime',
|
||||
label: formattedUptime.value,
|
||||
icon: TimerIcon,
|
||||
})
|
||||
}
|
||||
return stats
|
||||
})
|
||||
|
||||
const showProject = computed(() => !!props.serverProject)
|
||||
|
||||
const serverProjectLink = computed(() => {
|
||||
@@ -171,8 +214,8 @@ const serverProjectLink = computed(() => {
|
||||
})
|
||||
|
||||
function copyServerAddress() {
|
||||
if (!props.server?.net?.domain) return
|
||||
navigator.clipboard.writeText(`${props.server.net.domain}.modrinth.gg`)
|
||||
if (!serverAddress.value) return
|
||||
navigator.clipboard.writeText(serverAddress.value)
|
||||
addNotification({
|
||||
title: 'Server address copied',
|
||||
text: "Your server's address has been copied to your clipboard.",
|
||||
|
||||
Reference in New Issue
Block a user