mirror of
https://github.com/modrinth/code.git
synced 2026-08-26 17:44:50 +00:00
feat: server management in app (#5628)
* start new server settings tabs
* update properties tab to match design
* better stying in general tab
* feat: add suffix input for hostname field
* implement tables for allocations and DNS records
* add tags for dns record type
* small gap adjustment
* polish advanced page
* adjust properties page hierarchy
* fix searching properties, empty state and projection radius appearing
* pnpm prepr
* update copy to match designs
* fix suffix input component
* style fixes and match heading size
* small fix
* fix search allocations placeholder
* adjust table styles
* move all installation settings helper text to below input
* update icon to use overflow menu buttons
* fix modal to be consistent
* open advanced properties when search
* remove other and custom properties, and update styles
* remove hide/show all java versions
* handle mc 26
* refactor: move server settings pages into /ui and add app ServerSettingsModal
* hook up server pages for app
* add server page header to app
* hook up server settings modal
* use large size
* fix card box shadow style
* fix hostname input for app
* fix app/website card containers
* implement external tabs for billing and admin billing
* fix save banner fixed to parent instead of page body
* remove unused prop to FriendsList causing warning in app
* fix client-only not available for app
* fix bottom cut off
* wire node auth
* implement full copy buttons
* dedup copy button tailwind styles
* fix hover class not working in @apply
* fix spacing
* fix error validation styles
* apply consistent styles and spacing
* feat: update hosting server card (#5609)
* fix type errors
* fix some stylesheets not imported for storybook
* add server listing stories
* add fix for frontend stylesheet imports
* remove props.
* convert copy code to use tailwind
* update server listing component styles
* update server info label styles
* start status/player count info label, more style updates and fixes
* add new server card buttons
* hook up server cards and implement updated styles
* hook up on download button
* fix tauri throwing error when api returns 204 No Content
* hook up purchase server modal in app
* fix upgrading state loading icon
* pnpm prepr
* filter out servers past 30 days after cancellation
* do not apply opacity on lock or spiner icons
* fix disabled server icon background
* update pending change stage
* handle known suspension states
* refactor: reduce code duplication for server listing
* update disabled state text color
* fix loading icon color
* clean up copy
* fix disabled opacity for server card
* update server listing files kept to be countdown
* implement resubscribe modal
* implement proper provisioning state for resubscribe
* fix duplicate attribute and pnpm prepr
* feat: add shared UI package auth DI
* feat: update purchase server flow (#5714)
* implement server list empty state component
* fix stories and adjust spacing
* implement select plan design refresh
* implement auth for empty server list
* use refs instead of reactive
* pnpm prepr
* fix auth usage for empty servers list
* move app auth provider setup to src/providers/setup
* pnpm prepr
* fix max height
* style fix
* fix getCreds no auth is blocking api client
* implement servers guest plan modal and signin which redirects back to modal's next step
* refactor guest plan select logic into provider
* implement sign in or create account popup
* remove force empty serverList
* add download button for suspended mod and generic
* add handling for when user logs out
* QA pass style fixes
* more consistent page styles
* fix duplicate export
* refactor: remove all fallback stuff from resubscribe modal
* implement shared download latest backup util
* i18n pass
* pnpm prepr
* fix region being selected if ping failed
* pnpm prepr
* feat: servers in app finalization (#5744)
* feat: start on shared console implementation into logs and overview pages
* fix: terminal gap issues
* feat: swap word wrap for full screen
* fix: stats cards alignment
* fix: stats
* feat: fix console clear + remove copy
* fix: lint
* fix: use reset not clear
* feat: shared server header & overview page for app and website (#5736)
* feat: implement shared server header for app and website
* feat: implement wrapped overview page with shared composable and hook it up
* pnpm prepr
* fix: bugs
* qa: cleanup
* feat: root.vue shared layout
* feat: delete old options pages + fix discovery frontend
* fix: discovery
* fix: misc style/layout issues
* fix page padding
* fix: modal height jankiness
* feat: implement server install content in app and server setup modal with DI
* fix: spacing
* remove servers in app feature flag
* Revert "remove servers in app feature flag"
This reverts commit 86e284c4bd.
* fix: qa
* feat: remove legacy components from apps/frontend/src/components/ui/servers
---------
Co-authored-by: Calum H. (IMB11) <contact@cal.engineer>
* qa pass (#5738)
* fix: qa
* feat: qa
* fix: server icon fetch fails due to global node auth race condition overriding each other
* fix: lint
* fix: server icon upload/sync and centralize logic
* fix: server settings modal not closing for server reset
* fix: better server sorting
* feat: copy address in server listing card
* fix: notification panel in modal and when overlapping with action bar
* fix: empty server list empty state flashing when refresh, fixed by adding isReady auth flag
* feat: use floating action bar for save banner
* fix: saving state in save bar
* fix: edit server icon styling
* fix: confirm modal to have consistent buttons
* feat: loading animation for server panel + caching improvements for app
* pnpm prepr
* feat: search page deduplication (#5754)
* fix: action bar behind modal
* fix: remove warning modal for stopping
* fix: server cards states
* we hate webkit we hate webkit
* fix: update allocation creation to not use modal
* fix: properties tab spacing and styles
* feat: add files tab copy
* fix: advanced properties icon
* fix: remove back to all servers link
* feat: add files tab link in copy
* fix: server header styles to be consistent with instance
* fix: add header icons back
* feat: update instance settings icon to be consistent
* fix: icon container
* feat: upload state persistence across tabs
* fix: server labels text wrapping
* fix: use surface-5 border
* fix: loading spinner showing with onboarding below
* feat: new server button shows purchase modal in website
* fix: billing page not showing quarterly interval
* fix: server downgrade not showing updated subscription notification
* fix: server settings invalidate saved state and remove server context provider since its already provided in the page
* pnpm prepr
* add stripe publishable key to app build
* feat: console highlighting
* fix: rename servers title to modrinth hosting
* feat: search fix
* fix: qa/styles
* fix: ip click active and remove power dont ask again
* fix: qa
* feat: highlighting fix console
* fix: disable conflicts action
* fix: error dismiss bug
* feat: modal clarification
* fix: files perms issue
* fix: lint
* feat: modal fix
* enable show uptime
* fix: add loading state to edit server icon
* fix: notification panel take in has sidebar from settings
* fix: consistency pass on app settings
* fix: consistency pass on instance settings
* pnpm prepr
* fix: nagivate to billing button in app to go to website
* fix: stripe return url in app causing app to open modrinth.com in tauri
* refactor: better show polling UI code
* fix: new server polling comparison to use server ids instead of length
* fix: buttonstyled story
* fix: button styling
* fix: content.vue regression
* feat: project url redirects
* fix: breadcrumbs
* fix: purchase with newly added card
* fix: console ordering problems
* fix: app-frontend missing env config and staging environment
* fix: log syncing for instances and server panel accidentally
* fix: QA issues
* fix: server page loading state
* fix: stats card logic
* fix: lint
* fix: qa
* fix: console height padding
* fix: terminal padding + loading indicator
* feat: update medal server listing styling
* fix: no upgrade button for medal server listing in app
* fix: go to overview instead of content tab after onboarding
* fix: qa
* fix: teleport modals to body
* fix: logs tab + qa
* fix: local storage for user preferences
* fix: qa loading indic
* feat: considitonal debug and trace
* fix: jump to top on install bug
* feat: swap out server hard drive icon to server stack icon
* feat: servers in app feature flag default true
* fix: highlight row ufll
* fix: webkit thing onto a tag
* fix: input field
* fix: clear fix
* fix: lint
* fix: fmt
* feat: improve share modal and bring it back for sharing log
* pnpm prepr
* fix: menu overflowing
* feat: remove servers in app feature flag
* fix: server stat charts no longer showing color
* fix: library nav no primary state
* fix: better modal height and width
* fix: highlighting bugs
* fix: empty states
* fix: delay import to fix overview page slow load on MacOS
* fix: medal server listing too bright on light mode
* fix: admon analysis + fix logs
* fix: bug
* fix: clear purchase intent from sign-in after closing modal
* performance: improve server manage stats loading by splitting reactivity
* fix: deploy + admon + disable highlighting
* fix: clippy
---------
Co-authored-by: tdgao <mr.trumgao@gmail.com>
Co-authored-by: Truman Gao <106889354+tdgao@users.noreply.github.com>
* feat: temp wrangler
* fix: lint
* fix: logs upload
* fix: console empty state and admon regressions
* fix: fields
* feat: log deleting + prefetch for Logs.vue
* feat: move delete before share
* feat: clear endpoint
* feat: we ball!
---------
Co-authored-by: Calum H. <calum@modrinth.com>
Co-authored-by: Calum H. (IMB11) <contact@cal.engineer>
This commit is contained in:
co-authored by
Calum H.
tdgao
Calum H.
parent
a2a97d1313
commit
693a371d61
@@ -0,0 +1,443 @@
|
||||
import {
|
||||
type Archon,
|
||||
clearNodeAuthState,
|
||||
setNodeAuthState,
|
||||
type UploadState,
|
||||
} from '@modrinth/api-client'
|
||||
import type { Stats } from '@modrinth/utils'
|
||||
import type { ComputedRef, Ref } from 'vue'
|
||||
import { computed, reactive, ref, watch } from 'vue'
|
||||
|
||||
import type { FileOperation } from '../layouts/shared/files-tab/types'
|
||||
import { injectModrinthClient, provideModrinthServerContext } from '../providers'
|
||||
import type { BusyReason } from '../providers/server-context'
|
||||
import { defineMessage } from './i18n'
|
||||
import { useModrinthServersConsole } from './server-console'
|
||||
|
||||
type ReadableRef<T> = Ref<T> | ComputedRef<T>
|
||||
type SocketUnsubscriber = () => void
|
||||
|
||||
type ConnectSocketOptions = {
|
||||
force?: boolean
|
||||
extraSubscriptions?: (targetServerId: string) => SocketUnsubscriber[]
|
||||
}
|
||||
|
||||
type UseServerManageCoreRuntimeOptions = {
|
||||
serverId: ReadableRef<string>
|
||||
worldId: ReadableRef<string | null>
|
||||
server: ReadableRef<Archon.Servers.v0.Server | null | undefined>
|
||||
isSyncingContent: ReadableRef<boolean>
|
||||
markBackupCancelled?: (backupId: string) => void
|
||||
includeBackupBusyReasons?: boolean
|
||||
setDisconnectedOnAuthIncorrect?: boolean
|
||||
syncUptimeFromState?: boolean
|
||||
incrementUptimeLocally?: boolean
|
||||
eventGuard?: () => boolean
|
||||
onStateEvent?: (data: Archon.Websocket.v0.WSStateEvent) => void
|
||||
}
|
||||
|
||||
const createInitialStats = (): Stats => ({
|
||||
current: {
|
||||
cpu_percent: 0,
|
||||
ram_usage_bytes: 0,
|
||||
ram_total_bytes: 1,
|
||||
storage_usage_bytes: 0,
|
||||
storage_total_bytes: 0,
|
||||
},
|
||||
past: {
|
||||
cpu_percent: 0,
|
||||
ram_usage_bytes: 0,
|
||||
ram_total_bytes: 1,
|
||||
storage_usage_bytes: 0,
|
||||
storage_total_bytes: 0,
|
||||
},
|
||||
graph: {
|
||||
cpu: [],
|
||||
ram: [],
|
||||
},
|
||||
})
|
||||
|
||||
const appendGraphData = (dataArray: number[], newValue: number): number[] => {
|
||||
const updated = [...dataArray, newValue]
|
||||
if (updated.length > 10) updated.shift()
|
||||
return updated
|
||||
}
|
||||
|
||||
const mapPowerStateFromStateEvent = (
|
||||
data: Archon.Websocket.v0.WSStateEvent,
|
||||
): Archon.Websocket.v0.PowerState => {
|
||||
const powerMap: Record<Archon.Websocket.v0.FlattenedPowerState, Archon.Websocket.v0.PowerState> =
|
||||
{
|
||||
not_ready: 'stopped',
|
||||
starting: 'starting',
|
||||
running: 'running',
|
||||
stopping: 'stopping',
|
||||
idle:
|
||||
data.was_oom || (data.exit_code != null && data.exit_code !== 0) ? 'crashed' : 'stopped',
|
||||
}
|
||||
return powerMap[data.power_variant]
|
||||
}
|
||||
|
||||
export function useServerManageCoreRuntime(options: UseServerManageCoreRuntimeOptions) {
|
||||
const client = injectModrinthClient()
|
||||
const modrinthServersConsole = useModrinthServersConsole()
|
||||
|
||||
const shouldProcessEvent = () => (options.eventGuard ? options.eventGuard() : true)
|
||||
|
||||
const isConnected = ref(false)
|
||||
const isWsAuthIncorrect = ref(false)
|
||||
const serverPowerState = ref<Archon.Websocket.v0.PowerState>('stopped')
|
||||
const powerStateDetails = ref<{ oom_killed?: boolean; exit_code?: number }>()
|
||||
const isServerRunning = computed(() => serverPowerState.value === 'running')
|
||||
const stats = ref<Stats>(createInitialStats())
|
||||
const uptimeSeconds = ref(0)
|
||||
const backupsState = reactive(new Map())
|
||||
const fsAuth = ref<{ url: string; token: string } | null>(null)
|
||||
const fsOps = ref<Archon.Websocket.v0.FilesystemOperation[]>([])
|
||||
const fsQueuedOps = ref<Archon.Websocket.v0.QueuedFilesystemOp[]>([])
|
||||
const connectedSocketServerId = ref<string | null>(null)
|
||||
const socketUnsubscribers = ref<SocketUnsubscriber[]>([])
|
||||
const cpuData = ref<number[]>([])
|
||||
const ramData = ref<number[]>([])
|
||||
|
||||
let uptimeIntervalId: ReturnType<typeof setInterval> | null = null
|
||||
|
||||
const markBackupCancelled =
|
||||
options.markBackupCancelled ??
|
||||
((backupId: string) => {
|
||||
backupsState.delete(backupId)
|
||||
})
|
||||
|
||||
const busyReasons = computed<BusyReason[]>(() => {
|
||||
const reasons: BusyReason[] = []
|
||||
if (options.server.value?.status === 'installing') {
|
||||
reasons.push({
|
||||
reason: defineMessage({
|
||||
id: 'servers.busy.installing',
|
||||
defaultMessage: 'Server is installing',
|
||||
}),
|
||||
})
|
||||
}
|
||||
if (options.isSyncingContent.value) {
|
||||
reasons.push({
|
||||
reason: defineMessage({
|
||||
id: 'servers.busy.syncing-content',
|
||||
defaultMessage: 'Content sync in progress',
|
||||
}),
|
||||
})
|
||||
}
|
||||
if (options.includeBackupBusyReasons) {
|
||||
for (const entry of backupsState.values()) {
|
||||
if (entry.create?.state === 'ongoing') {
|
||||
reasons.push({
|
||||
reason: defineMessage({
|
||||
id: 'servers.busy.backup-creating',
|
||||
defaultMessage: 'Backup creation in progress',
|
||||
}),
|
||||
})
|
||||
break
|
||||
}
|
||||
if (entry.restore?.state === 'ongoing') {
|
||||
reasons.push({
|
||||
reason: defineMessage({
|
||||
id: 'servers.busy.backup-restoring',
|
||||
defaultMessage: 'Backup restore in progress',
|
||||
}),
|
||||
})
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return reasons
|
||||
})
|
||||
|
||||
const stopUptimeTicker = () => {
|
||||
if (uptimeIntervalId) {
|
||||
clearInterval(uptimeIntervalId)
|
||||
uptimeIntervalId = null
|
||||
}
|
||||
}
|
||||
|
||||
const startUptimeTicker = () => {
|
||||
if (!options.incrementUptimeLocally || uptimeIntervalId) return
|
||||
uptimeIntervalId = setInterval(() => {
|
||||
uptimeSeconds.value += 1
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
const updateStats = (currentStats: Stats['current']) => {
|
||||
if (!shouldProcessEvent()) return
|
||||
if (!isConnected.value) isConnected.value = true
|
||||
cpuData.value = appendGraphData(cpuData.value, currentStats.cpu_percent)
|
||||
ramData.value = appendGraphData(
|
||||
ramData.value,
|
||||
Math.floor((currentStats.ram_usage_bytes / currentStats.ram_total_bytes) * 100),
|
||||
)
|
||||
stats.value = {
|
||||
current: currentStats,
|
||||
past: { ...stats.value.current },
|
||||
graph: {
|
||||
cpu: cpuData.value,
|
||||
ram: ramData.value,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const updatePowerState = (
|
||||
state: Archon.Websocket.v0.PowerState,
|
||||
details?: { oom_killed?: boolean; exit_code?: number },
|
||||
) => {
|
||||
if (!shouldProcessEvent()) return
|
||||
serverPowerState.value = state
|
||||
powerStateDetails.value = state === 'crashed' ? details : undefined
|
||||
if (state === 'stopped' || state === 'crashed') {
|
||||
stopUptimeTicker()
|
||||
uptimeSeconds.value = 0
|
||||
}
|
||||
}
|
||||
|
||||
const handleLog = (data: Archon.Websocket.v0.WSLogEvent) => {
|
||||
if (!shouldProcessEvent()) return
|
||||
modrinthServersConsole.addLegacyLog(data.message)
|
||||
}
|
||||
|
||||
const handleLog4j = (data: Archon.Websocket.v0.WSLog4jEvent) => {
|
||||
if (!shouldProcessEvent()) return
|
||||
modrinthServersConsole.addLog4jEvent(data)
|
||||
}
|
||||
|
||||
const handleStats = (data: Archon.Websocket.v0.WSStatsEvent) => {
|
||||
updateStats({
|
||||
cpu_percent: data.cpu_percent,
|
||||
ram_usage_bytes: data.ram_usage_bytes,
|
||||
ram_total_bytes: data.ram_total_bytes,
|
||||
storage_usage_bytes: data.storage_usage_bytes,
|
||||
storage_total_bytes: data.storage_total_bytes,
|
||||
})
|
||||
}
|
||||
|
||||
const handlePowerState = (data: Archon.Websocket.v0.WSPowerStateEvent) => {
|
||||
if (data.state === 'crashed') {
|
||||
updatePowerState(data.state, {
|
||||
oom_killed: data.oom_killed,
|
||||
exit_code: data.exit_code,
|
||||
})
|
||||
} else {
|
||||
updatePowerState(data.state)
|
||||
}
|
||||
}
|
||||
|
||||
const handleState = (data: Archon.Websocket.v0.WSStateEvent) => {
|
||||
if (!shouldProcessEvent()) return
|
||||
options.onStateEvent?.(data)
|
||||
updatePowerState(mapPowerStateFromStateEvent(data), {
|
||||
exit_code: data.exit_code ?? undefined,
|
||||
oom_killed: data.was_oom,
|
||||
})
|
||||
|
||||
if (options.syncUptimeFromState && data.uptime > 0) {
|
||||
stopUptimeTicker()
|
||||
uptimeSeconds.value = data.uptime
|
||||
startUptimeTicker()
|
||||
}
|
||||
}
|
||||
|
||||
const handleUptime = (data: Archon.Websocket.v0.WSUptimeEvent) => {
|
||||
if (!shouldProcessEvent()) return
|
||||
stopUptimeTicker()
|
||||
uptimeSeconds.value = data.uptime
|
||||
startUptimeTicker()
|
||||
}
|
||||
|
||||
const handleAuthIncorrect = () => {
|
||||
if (!shouldProcessEvent()) return
|
||||
isWsAuthIncorrect.value = true
|
||||
if (options.setDisconnectedOnAuthIncorrect) {
|
||||
isConnected.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const handleAuthOk = () => {
|
||||
if (!shouldProcessEvent()) return
|
||||
isWsAuthIncorrect.value = false
|
||||
isConnected.value = true
|
||||
}
|
||||
|
||||
const clearSocketListeners = () => {
|
||||
for (const unsub of socketUnsubscribers.value) unsub()
|
||||
socketUnsubscribers.value = []
|
||||
}
|
||||
|
||||
const disconnectSocket = (targetServerId?: string) => {
|
||||
if (!targetServerId && !connectedSocketServerId.value) return
|
||||
|
||||
clearSocketListeners()
|
||||
|
||||
if (targetServerId) {
|
||||
client.archon.sockets.disconnect(targetServerId)
|
||||
}
|
||||
|
||||
stopUptimeTicker()
|
||||
connectedSocketServerId.value = null
|
||||
isConnected.value = false
|
||||
isWsAuthIncorrect.value = false
|
||||
serverPowerState.value = 'stopped'
|
||||
powerStateDetails.value = undefined
|
||||
uptimeSeconds.value = 0
|
||||
}
|
||||
|
||||
const connectSocket = async (
|
||||
targetServerId: string,
|
||||
connectOptions: ConnectSocketOptions = {},
|
||||
): Promise<boolean> => {
|
||||
if (
|
||||
connectedSocketServerId.value === targetServerId &&
|
||||
(isConnected.value || isWsAuthIncorrect.value)
|
||||
) {
|
||||
return true
|
||||
}
|
||||
|
||||
disconnectSocket(connectedSocketServerId.value ?? undefined)
|
||||
|
||||
try {
|
||||
const safeConnectOptions = connectOptions.force ? { force: true } : undefined
|
||||
await client.archon.sockets.safeConnect(targetServerId, safeConnectOptions)
|
||||
connectedSocketServerId.value = targetServerId
|
||||
isConnected.value = true
|
||||
isWsAuthIncorrect.value = false
|
||||
|
||||
modrinthServersConsole.clear()
|
||||
|
||||
const baseSubscriptions: SocketUnsubscriber[] = [
|
||||
client.archon.sockets.on(targetServerId, 'log', handleLog),
|
||||
client.archon.sockets.on(targetServerId, 'log4j', handleLog4j),
|
||||
client.archon.sockets.on(targetServerId, 'stats', handleStats),
|
||||
client.archon.sockets.on(targetServerId, 'state', handleState),
|
||||
client.archon.sockets.on(targetServerId, 'power-state', handlePowerState),
|
||||
client.archon.sockets.on(targetServerId, 'uptime', handleUptime),
|
||||
client.archon.sockets.on(targetServerId, 'auth-incorrect', handleAuthIncorrect),
|
||||
client.archon.sockets.on(targetServerId, 'auth-ok', handleAuthOk),
|
||||
]
|
||||
const extraSubscriptions = connectOptions.extraSubscriptions?.(targetServerId) ?? []
|
||||
socketUnsubscribers.value = [...baseSubscriptions, ...extraSubscriptions]
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error('[hosting/manage] Failed to connect server socket:', error)
|
||||
isConnected.value = false
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
const uploadState = ref<UploadState>({
|
||||
isUploading: false,
|
||||
currentFileName: null,
|
||||
currentFileProgress: 0,
|
||||
uploadedBytes: 0,
|
||||
totalBytes: 0,
|
||||
completedFiles: 0,
|
||||
totalFiles: 0,
|
||||
})
|
||||
const cancelUpload = ref<(() => void) | null>(null)
|
||||
|
||||
type QueuedOpWithState = Archon.Websocket.v0.QueuedFilesystemOp & { state: 'queued' }
|
||||
const dismissedOpIds = ref<Set<string>>(new Set())
|
||||
|
||||
const activeOperations = computed<FileOperation[]>(() => [
|
||||
...fsQueuedOps.value.map((x) => ({ ...x, state: 'queued' }) satisfies QueuedOpWithState),
|
||||
...(fsOps.value.filter((op) => !op.id || !dismissedOpIds.value.has(op.id)) as FileOperation[]),
|
||||
])
|
||||
|
||||
async function dismissOperation(opId: string, action: 'dismiss' | 'cancel') {
|
||||
if (action === 'dismiss') {
|
||||
dismissedOpIds.value = new Set([...dismissedOpIds.value, opId])
|
||||
}
|
||||
try {
|
||||
await client.kyros.files_v0.modifyOperation(opId, action)
|
||||
} catch (error) {
|
||||
if (action === 'dismiss') return
|
||||
console.error(`Failed to ${action} operation:`, error)
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => fsOps.value,
|
||||
(newOps) => {
|
||||
for (const op of newOps) {
|
||||
if (op.state === 'done' && op.id && !dismissedOpIds.value.has(op.id)) {
|
||||
setTimeout(() => {
|
||||
dismissOperation(op.id!, 'dismiss')
|
||||
}, 3000)
|
||||
}
|
||||
}
|
||||
},
|
||||
{ deep: true },
|
||||
)
|
||||
|
||||
const refreshFsAuth = async () => {
|
||||
if (!options.serverId.value) {
|
||||
fsAuth.value = null
|
||||
return
|
||||
}
|
||||
fsAuth.value = await client.archon.servers_v0.getFilesystemAuth(options.serverId.value)
|
||||
}
|
||||
|
||||
provideModrinthServerContext({
|
||||
get serverId() {
|
||||
return options.serverId.value
|
||||
},
|
||||
worldId: options.worldId as Ref<string | null>,
|
||||
server: options.server as Ref<Archon.Servers.v0.Server>,
|
||||
isConnected,
|
||||
isWsAuthIncorrect,
|
||||
powerState: serverPowerState,
|
||||
powerStateDetails,
|
||||
isServerRunning,
|
||||
stats,
|
||||
uptimeSeconds,
|
||||
backupsState,
|
||||
markBackupCancelled,
|
||||
isSyncingContent: options.isSyncingContent as Ref<boolean>,
|
||||
busyReasons,
|
||||
fsAuth,
|
||||
fsOps,
|
||||
fsQueuedOps,
|
||||
refreshFsAuth,
|
||||
uploadState,
|
||||
cancelUpload,
|
||||
activeOperations,
|
||||
dismissOperation,
|
||||
})
|
||||
|
||||
setNodeAuthState(() => fsAuth.value, refreshFsAuth)
|
||||
|
||||
const cleanupCoreRuntime = (targetServerId?: string) => {
|
||||
disconnectSocket(targetServerId ?? connectedSocketServerId.value ?? undefined)
|
||||
clearNodeAuthState()
|
||||
}
|
||||
|
||||
return {
|
||||
activeOperations,
|
||||
backupsState,
|
||||
busyReasons,
|
||||
cancelUpload,
|
||||
cleanupCoreRuntime,
|
||||
connectSocket,
|
||||
connectedSocketServerId,
|
||||
cpuData,
|
||||
disconnectSocket,
|
||||
dismissOperation,
|
||||
fsAuth,
|
||||
fsOps,
|
||||
fsQueuedOps,
|
||||
isConnected,
|
||||
isServerRunning,
|
||||
isWsAuthIncorrect,
|
||||
powerStateDetails,
|
||||
ramData,
|
||||
refreshFsAuth,
|
||||
serverPowerState,
|
||||
stats,
|
||||
uptimeSeconds,
|
||||
uploadState,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user