Files
Starlight_Launcher/apps/app-frontend/src/pages/library/Index.vue
T
Disy 51fb0c30f7
Axolotl desktop CI / guardrails (push) Has been cancelled
Repository checks / typos (push) Has been cancelled
Repository checks / tombi (push) Has been cancelled
Rust checks / shear (push) Has been cancelled
Sync source to CNB / Sync Git ref (push) Has been cancelled
Axolotl desktop CI / desktop (macos-latest) (push) Has been cancelled
Axolotl desktop CI / desktop (ubuntu-latest) (push) Has been cancelled
Axolotl desktop CI / desktop (windows-latest) (push) Has been cancelled
Axolotl desktop CI / website (push) Has been cancelled
Sync LobeHub models / sync (push) Has been cancelled
fix: 完善整合包同步与启动器交互
2026-09-16 17:01:22 +08:00

98 lines
3.3 KiB
Vue

<script setup lang="ts">
import { PlusIcon } from '@modrinth/assets'
import {
ButtonStyled,
defineMessages,
injectNotificationManager,
NavTabs,
useVIntl,
} from '@modrinth/ui'
import { onUnmounted, shallowRef } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import instanceThinkingImage from '@/assets/illustrations/instance-thinking.png'
import { useNetworkStatus } from '@/composables/useNetworkStatus'
import { DIRECT_LINKS_SYNCED_EVENT } from '@/helpers/direct-link-sync'
import { instance_listener } from '@/helpers/events.js'
import { list } from '@/helpers/instance'
import { useBreadcrumbs } from '@/store/breadcrumbs.js'
const { handleError } = injectNotificationManager()
const route = useRoute()
const router = useRouter()
const breadcrumbs = useBreadcrumbs()
const { formatMessage } = useVIntl()
const messages = defineMessages({
library: { id: 'app.library.title', defaultMessage: 'Library' },
allInstances: { id: 'app.library.tabs.all-instances', defaultMessage: 'All instances' },
modpacks: { id: 'app.library.tabs.modpacks', defaultMessage: 'Modpacks' },
custom: { id: 'app.library.tabs.custom', defaultMessage: 'Custom' },
shared: { id: 'app.library.tabs.shared', defaultMessage: 'Shared with me' },
saved: { id: 'app.library.tabs.saved', defaultMessage: 'Saved' },
noInstances: { id: 'app.library.no-instances', defaultMessage: 'No instances found' },
createInstance: {
id: 'app.library.create-instance',
defaultMessage: 'Create new instance',
},
})
breadcrumbs.setRootContext({ name: formatMessage(messages.library), link: route.path })
const instances = shallowRef(await list().catch(handleError))
const refreshInstances = async () => {
instances.value = await list().catch(handleError)
}
window.addEventListener(DIRECT_LINKS_SYNCED_EVENT, refreshInstances)
const { offline } = useNetworkStatus()
const unlistenInstance = await instance_listener(async () => {
await refreshInstances()
})
onUnmounted(() => {
unlistenInstance()
window.removeEventListener(DIRECT_LINKS_SYNCED_EVENT, refreshInstances)
})
</script>
<template>
<div data-onboarding-id="library-content" class="p-6 flex flex-col gap-3">
<h1 class="m-0 text-2xl hidden">{{ formatMessage(messages.library) }}</h1>
<NavTabs
:links="[
{ label: formatMessage(messages.allInstances), href: `/library` },
{ label: formatMessage(messages.modpacks), href: `/library/modpacks` },
{ label: formatMessage(messages.custom), href: `/library/custom` },
{ label: formatMessage(messages.shared), href: `/library/shared`, shown: false },
{ label: formatMessage(messages.saved), href: `/library/saved`, shown: false },
]"
/>
<template v-if="instances && instances.length > 0">
<RouterView v-if="route.path.startsWith('/library')" :instances="instances" />
</template>
<div v-else class="flex flex-col items-center justify-center h-full gap-3">
<img
:src="instanceThinkingImage"
alt=""
aria-hidden="true"
class="h-40 w-40 object-contain"
draggable="false"
/>
<h3 class="m-0">{{ formatMessage(messages.noInstances) }}</h3>
<ButtonStyled color="brand">
<button
data-onboarding-id="create-instance"
:disabled="offline"
@click="router.push('/create')"
>
<PlusIcon />
{{ formatMessage(messages.createInstance) }}
</button>
</ButtonStyled>
</div>
</div>
</template>