feat: implement world creation flow routes

This commit is contained in:
Calum H. (IMB11)
2026-06-26 17:09:22 +01:00
parent 0a451d9f9a
commit 54e6fe09cd
65 changed files with 834 additions and 1307 deletions
@@ -191,12 +191,12 @@
"app.browse.server.installing": {
"message": "Installing"
},
"app.content-install.no-compatible-versions": {
"message": "No available versions match {compatibilityLabel}. Select a version to install anyway. Dependencies will not be installed automatically."
},
"app.browse.server.world-fallback-name": {
"message": "Instance"
},
"app.content-install.no-compatible-versions": {
"message": "No available versions match {compatibilityLabel}. Select a version to install anyway. Dependencies will not be installed automatically."
},
"app.creation-modal.installing-modpack.description": {
"message": "{fileName}"
},
@@ -67,9 +67,9 @@ const messages = defineMessages({
id: 'discover.install.error.no-server-world',
defaultMessage: 'No server instance is available for install.',
},
backToSetup: {
id: 'discover.install.back-to-setup',
defaultMessage: 'Back to setup',
backToCreateInstance: {
id: 'discover.install.back-to-create-instance',
defaultMessage: 'Back to create instance',
},
cancelReset: {
id: 'discover.install.cancel-reset',
@@ -83,6 +83,14 @@ const messages = defineMessages({
id: 'discover.install.heading.reset-modpack',
defaultMessage: 'Selecting modpack to install after reset',
},
createInstanceModpackHeading: {
id: 'discover.install.heading.create-instance-modpack',
defaultMessage: 'Selecting modpack base',
},
createInstanceName: {
id: 'discover.install.create-instance-name',
defaultMessage: 'Create instance',
},
worldFallbackName: {
id: 'discover.install.world-fallback-name',
defaultMessage: 'Instance',
@@ -569,11 +577,6 @@ export function useServerInstallContent({
}
async function serverInstall(project: ServerInstallSearchResult) {
if (!serverData.value || !currentServerId.value || !currentWorldId.value) {
handleError(new Error('No server to install to.'))
return
}
if (!browseSearchState) {
handleError(new Error('Search state is not ready.'))
return
@@ -581,6 +584,17 @@ export function useServerInstallContent({
const contentType = getCurrentServerInstallType()
const isModpack = contentType === 'modpack'
const isCreateInstanceFlow =
fromContext.value === 'create-instance' || fromContext.value === 'onboarding'
if (
!serverData.value ||
!currentServerId.value ||
(!currentWorldId.value && (!isCreateInstanceFlow || !isModpack))
) {
handleError(new Error('No server to install to.'))
return
}
try {
if (!isModpack && queuedServerInstallProjectIds.value.has(project.project_id)) {
@@ -654,9 +668,41 @@ export function useServerInstallContent({
}
async function onModpackFlowCreate(config: CreationFlowContextValue) {
if (!currentServerId.value || !currentWorldId.value || !config.modpackSelection.value) return
if (!currentServerId.value || !config.modpackSelection.value) return
try {
if (fromContext.value === 'create-instance' || fromContext.value === 'onboarding') {
const createdWorld = await client.archon.servers_v1.createWorld(currentServerId.value, {
name: config.worldName.value.trim(),
properties: config.buildProperties(),
content: {
content_variant: 'modpack',
spec: {
platform: 'modrinth',
project_id: config.modpackSelection.value.projectId,
version_id: config.modpackSelection.value.versionId,
},
},
} satisfies Archon.Servers.v1.CreateWorld)
if (fromContext.value === 'onboarding') {
await client.archon.servers_v1.endIntro(currentServerId.value)
}
await Promise.all([
queryClient.invalidateQueries({
queryKey: ['servers', 'worlds', 'summary', 'v1', currentServerId.value],
}),
queryClient.invalidateQueries({ queryKey: ['servers', 'detail', currentServerId.value] }),
queryClient.invalidateQueries({
queryKey: ['servers', 'v1', 'detail', currentServerId.value],
}),
])
navigateTo(getServerInstanceContentPath(currentServerId.value, createdWorld.id))
return
}
if (!currentWorldId.value) return
await client.archon.content_v1.installContent(currentServerId.value, currentWorldId.value, {
content_variant: 'modpack',
spec: {
@@ -668,15 +714,7 @@ export function useServerInstallContent({
properties: config.buildProperties(),
} satisfies Archon.Content.v1.InstallWorldContent)
if (fromContext.value === 'onboarding') {
await client.archon.servers_v1.endIntro(currentServerId.value)
queryClient.invalidateQueries({ queryKey: ['servers', 'detail', currentServerId.value] })
navigateTo(
getServerInstanceContentPath(currentServerId.value, currentWorldId.value ?? null),
)
} else {
navigateTo(`/hosting/manage/${currentServerId.value}?openSettings=installation`)
}
navigateTo(`/hosting/manage/${currentServerId.value}?openSettings=installation`)
} catch (e) {
handleError(new Error(`Error installing modpack: ${e}`))
config.loading.value = false
@@ -686,6 +724,8 @@ export function useServerInstallContent({
const serverBackUrl = computed(() => {
if (!serverData.value) return ''
const id = serverData.value.server_id
if (fromContext.value === 'create-instance')
return `/hosting/manage/${id}/instances?resumeModal=create-instance`
if (fromContext.value === 'onboarding') return `/hosting/manage/${id}?resumeModal=setup-type`
if (fromContext.value === 'reset-server')
return `/hosting/manage/${id}?openSettings=installation`
@@ -698,7 +738,8 @@ export function useServerInstallContent({
}
const serverBackLabel = computed(() => {
if (fromContext.value === 'onboarding') return formatMessage(messages.backToSetup)
if (fromContext.value === 'create-instance') return formatMessage(messages.backToCreateInstance)
if (fromContext.value === 'onboarding') return formatMessage(messages.backToCreateInstance)
if (fromContext.value === 'reset-server') return formatMessage(messages.cancelReset)
return formatMessage(messages.backToServer)
})
@@ -706,9 +747,13 @@ export function useServerInstallContent({
const serverBrowseHeading = computed(() =>
fromContext.value === 'reset-server'
? formatMessage(messages.resetModpackHeading)
: formatMessage(commonMessages.installingContentLabel),
: fromContext.value === 'create-instance' || fromContext.value === 'onboarding'
? formatMessage(messages.createInstanceModpackHeading)
: formatMessage(commonMessages.installingContentLabel),
)
const currentWorld = computed(() => {
if (fromContext.value === 'create-instance') return null
const full = serverFullData.value
if (!full) return null
@@ -723,7 +768,10 @@ export function useServerInstallContent({
const installContext = computed(() => {
if (!serverData.value) return null
return {
name: currentWorld.value?.name ?? formatMessage(messages.worldFallbackName),
name:
fromContext.value === 'create-instance'
? formatMessage(messages.createInstanceName)
: (currentWorld.value?.name ?? formatMessage(messages.worldFallbackName)),
loader: currentWorld.value?.content?.modloader ?? serverData.value.loader ?? '',
loaderVersion:
currentWorld.value?.content?.modloader_version ?? serverData.value.loader_version ?? '',
@@ -741,7 +789,7 @@ export function useServerInstallContent({
installProgress: queuedInstallProgress.value,
clearQueued: clearQueuedServerInstalls,
clearSelected: clearQueuedServerInstalls,
onBack: flushQueuedServerInstalls,
onBack: fromContext.value === 'create-instance' ? undefined : flushQueuedServerInstalls,
discardSelectedAndBack: discardQueuedServerInstallsAndBack,
installSelected: installQueuedServerInstallsAndBack,
}
@@ -1805,9 +1805,6 @@
"discover.install.back-to-server": {
"message": "Zurück zum Server"
},
"discover.install.back-to-setup": {
"message": "Zurück zur Einrichtung"
},
"discover.install.cancel-reset": {
"message": "Reset abbrechen"
},
@@ -1805,9 +1805,6 @@
"discover.install.back-to-server": {
"message": "Zurück zum Server"
},
"discover.install.back-to-setup": {
"message": "Zurück zur Einrichtung"
},
"discover.install.cancel-reset": {
"message": "Zurücksetzung abbrechen"
},
+9 -3
View File
@@ -1946,21 +1946,27 @@
"dashboard.withdraw.error.tax-form.title": {
"message": "Please complete tax form"
},
"discover.install.back-to-create-instance": {
"message": "Back to create instance"
},
"discover.install.back-to-server": {
"message": "Back to server"
},
"discover.install.back-to-setup": {
"message": "Back to setup"
},
"discover.install.cancel-reset": {
"message": "Cancel reset"
},
"discover.install.create-instance-name": {
"message": "Create instance"
},
"discover.install.error.no-server-world": {
"message": "No server instance is available for install."
},
"discover.install.error.unsupported-content-type": {
"message": "This content type cannot be installed to a server from Discover."
},
"discover.install.heading.create-instance-modpack": {
"message": "Selecting modpack base"
},
"discover.install.heading.reset-modpack": {
"message": "Selecting modpack to install after reset"
},
@@ -1847,9 +1847,6 @@
"discover.install.back-to-server": {
"message": "Volver al servidor"
},
"discover.install.back-to-setup": {
"message": "Volver a configuración"
},
"discover.install.cancel-reset": {
"message": "Cancelar reinicio"
},
@@ -1841,9 +1841,6 @@
"discover.install.back-to-server": {
"message": "Volver al server"
},
"discover.install.back-to-setup": {
"message": "Volver a configuración"
},
"discover.install.cancel-reset": {
"message": "Cancelar reinicio"
},
@@ -1847,9 +1847,6 @@
"discover.install.back-to-server": {
"message": "Retour au serveur"
},
"discover.install.back-to-setup": {
"message": "Retour au setup"
},
"discover.install.cancel-reset": {
"message": "Annuler la réinitialisation"
},
@@ -1688,9 +1688,6 @@
"discover.install.back-to-server": {
"message": "Vissza a szerverhez"
},
"discover.install.back-to-setup": {
"message": "Vissza a beállításhoz"
},
"discover.install.cancel-reset": {
"message": "Visszaállítás visszavonása"
},
@@ -1838,9 +1838,6 @@
"discover.install.back-to-server": {
"message": "Torna al server"
},
"discover.install.back-to-setup": {
"message": "Torna alla configurazione"
},
"discover.install.cancel-reset": {
"message": "Annulla ripristino"
},
@@ -1319,9 +1319,6 @@
"discover.install.back-to-server": {
"message": "서버로 돌아가기"
},
"discover.install.back-to-setup": {
"message": "설정으로 돌아가기"
},
"discover.install.cancel-reset": {
"message": "리셋 취소"
},
@@ -1688,9 +1688,6 @@
"discover.install.back-to-server": {
"message": "Kembali ke pelayan"
},
"discover.install.back-to-setup": {
"message": "Kembali ke persediaan"
},
"discover.install.cancel-reset": {
"message": "Batalkan penetapan semula"
},
@@ -1844,9 +1844,6 @@
"discover.install.back-to-server": {
"message": "Powróć do serwera"
},
"discover.install.back-to-setup": {
"message": "Powróć do ustawiania"
},
"discover.install.cancel-reset": {
"message": "Anuluj resetowanie"
},
@@ -1844,9 +1844,6 @@
"discover.install.back-to-server": {
"message": "Voltar ao servidor"
},
"discover.install.back-to-setup": {
"message": "Voltar à configuração"
},
"discover.install.cancel-reset": {
"message": "Cancelar redefinição"
},
@@ -1829,9 +1829,6 @@
"discover.install.back-to-server": {
"message": "Вернуться к серверу"
},
"discover.install.back-to-setup": {
"message": "Вернуться к установке"
},
"discover.install.cancel-reset": {
"message": "Отменить сброс"
},
@@ -1805,9 +1805,6 @@
"discover.install.back-to-server": {
"message": "Sunucuya geri dön"
},
"discover.install.back-to-setup": {
"message": "Sunucuya geri dön"
},
"discover.install.cancel-reset": {
"message": "Sıfırlamayı iptal et"
},
@@ -1625,9 +1625,6 @@
"discover.install.back-to-server": {
"message": "Повернутися до сервера"
},
"discover.install.back-to-setup": {
"message": "Повернутися до налаштування"
},
"discover.install.cancel-reset": {
"message": "Скасувати скидання"
},
@@ -1805,9 +1805,6 @@
"discover.install.back-to-server": {
"message": "Quay lại máy chủ"
},
"discover.install.back-to-setup": {
"message": "Quay lại cài đặt"
},
"discover.install.cancel-reset": {
"message": "Hủy cài lại"
},
@@ -1802,9 +1802,6 @@
"discover.install.back-to-server": {
"message": "返回服务器"
},
"discover.install.back-to-setup": {
"message": "返回设置"
},
"discover.install.cancel-reset": {
"message": "取消重置"
},
@@ -1847,9 +1847,6 @@
"discover.install.back-to-server": {
"message": "回到伺服器"
},
"discover.install.back-to-setup": {
"message": "回到設定"
},
"discover.install.cancel-reset": {
"message": "取消重設"
},
@@ -584,7 +584,13 @@ provideBrowseManager({
<CreationFlowModal
v-if="currentServerId && projectType?.id === 'modpack'"
ref="onboardingModalRef"
:type="fromContext === 'reset-server' ? 'reset-server' : 'server-onboarding'"
:type="
fromContext === 'reset-server'
? 'reset-server'
: fromContext === 'create-instance' || fromContext === 'onboarding'
? 'world'
: 'server-onboarding'
"
:available-loaders="['vanilla', 'fabric', 'neoforge', 'forge', 'quilt', 'paper', 'purpur']"
:show-snapshot-toggle="true"
:on-back="onOnboardingBack"
@@ -51,15 +51,18 @@ const client = injectModrinthClient()
const queryClient = useQueryClient()
if (serverId) {
try {
await queryClient.ensureQueryData({
await Promise.allSettled([
queryClient.ensureQueryData({
queryKey: ['servers', 'detail', serverId],
queryFn: () => client.archon.servers_v0.get(serverId)!,
staleTime: 30_000,
})
} catch {
// Let mounted layouts' useQuery surface errors; do not fail route setup.
}
}),
queryClient.ensureQueryData({
queryKey: ['servers', 'v1', 'detail', serverId],
queryFn: () => client.archon.servers_v1.get(serverId),
staleTime: 30_000,
}),
])
}
const auth = (await useAuth()) as unknown as {
@@ -25,7 +25,7 @@ await Promise.allSettled([
queryFn: () => client.archon.servers_v1.get(serverId),
staleTime: 30_000,
}),
queryClient.prefetchInfiniteQuery({
queryClient.ensureInfiniteQueryData({
queryKey: [
'servers',
'action-log',