@@ -38,6 +38,7 @@ import {
3838 CreationFlowModal ,
3939 defineMessages ,
4040 I18nDebugPanel ,
41+ LoadingBar ,
4142 NewsArticleCard ,
4243 NotificationPanel ,
4344 OverflowMenu ,
@@ -52,7 +53,7 @@ import {
5253 useVIntl ,
5354} from ' @modrinth/ui'
5455import { formatBytes , renderString } from ' @modrinth/utils'
55- import { useQuery } from ' @tanstack/vue-query'
56+ import { useQuery , useQueryClient } from ' @tanstack/vue-query'
5657import { getVersion } from ' @tauri-apps/api/app'
5758import { invoke } from ' @tauri-apps/api/core'
5859import { getCurrentWindow } from ' @tauri-apps/api/window'
@@ -65,7 +66,6 @@ import { computed, onMounted, onUnmounted, provide, ref, watch } from 'vue'
6566import { RouterView , useRoute , useRouter } from ' vue-router'
6667
6768import ModrinthAppLogo from ' @/assets/modrinth_app.svg?component'
68- import ModrinthLoadingIndicator from ' @/components/LoadingIndicatorBar.vue'
6969import AccountsCard from ' @/components/ui/AccountsCard.vue'
7070import Breadcrumbs from ' @/components/ui/Breadcrumbs.vue'
7171import ErrorModal from ' @/components/ui/ErrorModal.vue'
@@ -113,8 +113,9 @@ import {
113113import { createServerInstall , provideServerInstall } from ' @/providers/server-install'
114114import { setupProviders } from ' @/providers/setup'
115115import { setupAuthProvider } from ' @/providers/setup/auth'
116+ import { setupLoadingStateProvider } from ' @/providers/setup/loading-state'
116117import { useError } from ' @/store/error.js'
117- import { useLoading , useTheming } from ' @/store/state'
118+ import { useTheming } from ' @/store/state'
118119
119120import { generateSkinPreviews } from ' ./helpers/rendering/batch-skin-renderer'
120121import { get_available_capes , get_available_skins } from ' ./helpers/skins'
@@ -420,9 +421,11 @@ const handleClose = async () => {
420421const router = useRouter ()
421422const route = useRoute ()
422423
423- const loading = useLoading ()
424+ const loading = setupLoadingStateProvider ()
424425loading .setEnabled (false )
425- loading .startLoading ()
426+ let initialLoadToken = loading .begin ()
427+ let routerToken = null
428+ let suspenseToken = null
426429
427430let suspensePending = false
428431
@@ -435,7 +438,8 @@ const sidebarOverlayScrollbarsOptions = Object.freeze({
435438
436439router .beforeEach (() => {
437440 suspensePending = false
438- loading .startLoading ()
441+ if (routerToken) loading .end (routerToken)
442+ routerToken = loading .begin ()
439443})
440444router .afterEach ((to , from , failure ) => {
441445 trackEvent (' PageView' , {
@@ -445,11 +449,83 @@ router.afterEach((to, from, failure) => {
445449 })
446450 setTimeout (() => {
447451 if (! suspensePending && stateInitialized .value ) {
448- loading .stopLoading ()
452+ if (initialLoadToken) {
453+ loading .end (initialLoadToken)
454+ initialLoadToken = null
455+ }
456+ if (routerToken) {
457+ loading .end (routerToken)
458+ routerToken = null
459+ }
449460 }
450461 }, 100 )
451462})
452463
464+ function onSuspensePending () {
465+ suspensePending = true
466+ if (suspenseToken) loading .end (suspenseToken)
467+ suspenseToken = loading .begin ()
468+ }
469+
470+ function onSuspenseResolve () {
471+ if (suspenseToken) {
472+ loading .end (suspenseToken)
473+ suspenseToken = null
474+ }
475+ if (routerToken) {
476+ loading .end (routerToken)
477+ routerToken = null
478+ }
479+ }
480+
481+ const queryClient = useQueryClient ()
482+
483+ watch (stateInitialized, (ready ) => {
484+ if (ready) {
485+ if (initialLoadToken) {
486+ loading .end (initialLoadToken)
487+ initialLoadToken = null
488+ }
489+ if (routerToken) {
490+ loading .end (routerToken)
491+ routerToken = null
492+ }
493+
494+ queryClient .prefetchQuery ({
495+ queryKey: [' servers' ],
496+ queryFn: async () => {
497+ const response = await tauriApiClient .archon .servers_v0 .list ({ limit: 100 })
498+ const hasMedalServers = response .servers .some ((s ) => s .is_medal )
499+ if (hasMedalServers) {
500+ const subscriptions = await tauriApiClient .labrinth .billing_internal .getSubscriptions ()
501+ for (const server of response .servers ) {
502+ if (server .is_medal ) {
503+ const sub = subscriptions .find ((s ) => s .metadata ? .id === server .server_id )
504+ if (sub) {
505+ server .medal_expires = new Date (
506+ new Date (sub .created ).getTime () + 5 * 86400000 ,
507+ ).toISOString ()
508+ }
509+ }
510+ }
511+ }
512+ return response
513+ },
514+ staleTime: 30_000 ,
515+ })
516+ queryClient .prefetchQuery ({
517+ queryKey: [' billing' , ' subscriptions' ],
518+ queryFn : () => tauriApiClient .labrinth .billing_internal .getSubscriptions (),
519+ staleTime: 30_000 ,
520+ })
521+ queryClient .prefetchQuery ({
522+ queryKey: [' billing' , ' payments' ],
523+ queryFn : () => tauriApiClient .labrinth .billing_internal .getPayments (),
524+ staleTime: 30_000 ,
525+ })
526+ }
527+ })
528+
453529const error = useError ()
454530const errorModal = ref ()
455531const minecraftAuthErrorModal = ref ()
@@ -1236,7 +1312,7 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
12361312 width: 'calc(100% - var(--left-bar-width) - var(--right-bar-width))',
12371313 }"
12381314 >
1239- < ModrinthLoadingIndicator / >
1315+ < LoadingBar position = " absolute " / >
12401316 < / div>
12411317 < div
12421318 v- if = " themeStore.featureFlags.page_path"
@@ -1272,19 +1348,7 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
12721348 < / Admonition>
12731349 < RouterView v- slot= " { Component }" >
12741350 < template v- if = " Component" >
1275- < Suspense
1276- @pending= "
1277- () => {
1278- suspensePending = true
1279- loading.startLoading()
1280- }
1281- "
1282- @resolve= "
1283- () => {
1284- loading.stopLoading()
1285- }
1286- "
1287- >
1351+ < Suspense @pending= " onSuspensePending" @resolve= " onSuspenseResolve" >
12881352 < component : is= " Component" >< / component>
12891353 < / Suspense>
12901354 < / template>
0 commit comments