feat: shared loading state + cleanup loading state management (#5835)

* feat: implement shared loading bar component and polished loading states across the app

* feat: align loading states + ensureQueryData changes

* fix: lint + bugs

* fix: skeleton for manage servers page

* fix: merge conflict fix
This commit is contained in:
Calum H.
2026-04-18 19:46:39 +01:00
committed by GitHub
parent 3e32901737
commit 176d4301c3
47 changed files with 2063 additions and 1371 deletions

View File

@@ -3,6 +3,7 @@ import { provideNotificationManager } from '@modrinth/ui'
import { FrontendNotificationManager } from './frontend-notifications'
import { setupAuthProvider } from './setup/auth'
import { setupFilePickerProvider } from './setup/file-picker'
import { setupLoadingStateProvider } from './setup/loading-state'
import { setupModrinthClientProvider } from './setup/modrinth-client'
import { setupPageContextProvider } from './setup/page-context'
import { setupTagsProvider } from './setup/tags'
@@ -15,4 +16,5 @@ export function setupProviders(auth: Awaited<ReturnType<typeof useAuth>>) {
setupTagsProvider()
setupFilePickerProvider()
setupPageContextProvider()
setupLoadingStateProvider()
}

View File

@@ -0,0 +1,49 @@
import type { LoadingStateProvider } from '@modrinth/ui'
import { createLoadingStateCore, provideLoadingState } from '@modrinth/ui'
import { watch } from 'vue'
/**
* Initialize the cross-platform loading-state provider for the website.
*
* Responsibilities:
* 1. Own the token-based ref-counter that drives `LoadingBar` and `ReadyTransition`.
* 2. Bridge the legacy `useState('loading')` global so the many existing
* `startLoading()` / `stopLoading()` call sites continue to raise the bar.
* 3. Register Nuxt `page:start` / `page:finish` hooks so route navigation
* auto-fires the bar (replaces the behavior previously inside
* `modrinth-loading-indicator.ts`).
*/
export function setupLoadingStateProvider(): LoadingStateProvider {
const provider = createLoadingStateCore({ barEnabled: true })
provideLoadingState(provider)
const legacyState = useLoading()
let legacyToken: symbol | null = null
watch(
legacyState,
(value) => {
if (value && !legacyToken) {
legacyToken = provider.begin()
} else if (!value && legacyToken) {
provider.end(legacyToken)
legacyToken = null
}
},
{ immediate: true },
)
const nuxtApp = useNuxtApp()
let pageToken: symbol | null = null
nuxtApp.hook('page:start', () => {
if (pageToken) provider.end(pageToken)
pageToken = provider.begin()
})
nuxtApp.hook('page:finish', () => {
if (pageToken) {
provider.end(pageToken)
pageToken = null
}
})
return provider
}