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
98 lines
3.3 KiB
Vue
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>
|