Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(theme-default): add page load progressbar #1264

Merged
merged 8 commits into from Sep 1, 2022

Conversation

wxsms
Copy link
Member

@wxsms wxsms commented Aug 31, 2022

close #1138

@wxsms wxsms changed the title feat: add page load progressbar feat(theme-default): add page load progressbar Aug 31, 2022
@brc-dd
Copy link
Member

brc-dd commented Aug 31, 2022

This ideally should be opt-in. Another thing, I don't think mutation of router on each call of useRouter is a good idea. onBeforeRouteChange and onAfterRouteChanged can probably be supported through the theme object itself.

Diff (with main)
diff --git a/src/client/app/index.ts b/src/client/app/index.ts
index 84bd1c2..86f68dd 100644
--- a/src/client/app/index.ts
+++ b/src/client/app/index.ts
@@ -101,26 +101,31 @@ function newRouter(): Router {
   let isInitialPageLoad = inBrowser
   let initialPath: string
 
-  return createRouter((path) => {
-    let pageFilePath = pathToFile(path)
-
-    if (isInitialPageLoad) {
-      initialPath = pageFilePath
-    }
-
-    // use lean build if this is the initial page load or navigating back
-    // to the initial loaded path (the static vnodes already adopted the
-    // static content on that load so no need to re-fetch the page)
-    if (isInitialPageLoad || initialPath === pageFilePath) {
-      pageFilePath = pageFilePath.replace(/\.js$/, '.lean.js')
-    }
-
-    if (inBrowser) {
-      isInitialPageLoad = false
-    }
-
-    return import(/*@vite-ignore*/ pageFilePath)
-  }, NotFound)
+  return createRouter(
+    (path) => {
+      let pageFilePath = pathToFile(path)
+
+      if (isInitialPageLoad) {
+        initialPath = pageFilePath
+      }
+
+      // use lean build if this is the initial page load or navigating back
+      // to the initial loaded path (the static vnodes already adopted the
+      // static content on that load so no need to re-fetch the page)
+      if (isInitialPageLoad || initialPath === pageFilePath) {
+        pageFilePath = pageFilePath.replace(/\.js$/, '.lean.js')
+      }
+
+      if (inBrowser) {
+        isInitialPageLoad = false
+      }
+
+      return import(/*@vite-ignore*/ pageFilePath)
+    },
+    NotFound,
+    Theme.onBeforeRouteChange,
+    Theme.onAfterRouteChanged
+  )
 }
 
 if (inBrowser) {
diff --git a/src/client/app/router.ts b/src/client/app/router.ts
index 23d0027..553382f 100644
--- a/src/client/app/router.ts
+++ b/src/client/app/router.ts
@@ -35,11 +35,14 @@ interface PageModule {
 
 export function createRouter(
   loadPageModule: (path: string) => Promise<PageModule>,
-  fallbackComponent?: Component
+  fallbackComponent?: Component,
+  onBeforeRouteChange?: (to: string) => void | Promise<void>,
+  onAfterRouteChanged?: (to: string) => void | Promise<void>
 ): Router {
   const route = reactive(getDefaultRoute())
 
-  function go(href: string = inBrowser ? location.href : '/') {
+  async function go(href: string = inBrowser ? location.href : '/') {
+    await onBeforeRouteChange?.(href)
     const url = new URL(href, fakeHost)
     if (siteDataRef.value.cleanUrls === 'disabled') {
       // ensure correct deep link so page refresh lands on correct files.
@@ -54,7 +57,8 @@ export function createRouter(
       history.replaceState({ scrollPosition: window.scrollY }, document.title)
       history.pushState(null, '', href)
     }
-    return loadPage(href)
+    await loadPage(href)
+    await onAfterRouteChanged?.(href)
   }
 
   let latestPendingPath: string | null = null
diff --git a/src/client/app/theme.ts b/src/client/app/theme.ts
index 6c13fda..edc1cc2 100644
--- a/src/client/app/theme.ts
+++ b/src/client/app/theme.ts
@@ -13,4 +13,6 @@ export interface Theme {
   NotFound?: Component
   enhanceApp?: (ctx: EnhanceAppContext) => void
   setup?: () => void
+  onBeforeRouteChange?: (to: string) => void | Promise<void>
+  onAfterRouteChanged?: (to: string) => void | Promise<void>
 }

Also, I'm not sure if we should have this in the default theme. People can easily do this:

// .vitepress/theme/index.ts

import DefaultTheme from 'vitepress/theme'
import nprogress from 'nprogress'
import 'nprogress/nprogress.css'

export default {
  ...DefaultTheme,
  onBeforeRouteChange: () => {
    nprogress.start();
  },
  onAfterRouteChanged: () => {
    nprogress.done(true);
  }
}

Thoughts @kiaking?

@wxsms
Copy link
Member Author

wxsms commented Sep 1, 2022

I don't think mutation of router on each call of useRouter is a good idea

how about enhanceApp? We can attach these events to the router object inside enhanceApp. Therefore no new options on Theme object is needed.

Also, I'm not sure if we should have this in the default theme

As I pointed out in the issue, I think that it's an important feature for users using slow network.

@wxsms
Copy link
Member Author

wxsms commented Sep 1, 2022

I just updated the PR base on enhanceApp and the review comments. Please take a look. Thanks.

@brc-dd
Copy link
Member

brc-dd commented Sep 1, 2022

Also update theme.d.ts:

diff --git a/theme.d.ts b/theme.d.ts
index cbb9cdf..3d0fac1 100644
--- a/theme.d.ts
+++ b/theme.d.ts
@@ -1,5 +1,6 @@
 // so that users can do `import DefaultTheme from 'vitepress/theme'`
 import type { ComponentOptions } from 'vue'
+import { EnhanceAppContext } from './dist/client/index.js'
 
 export const VPHomeHero: ComponentOptions
 export const VPHomeFeatures: ComponentOptions
@@ -13,6 +14,7 @@ export const VPTeamMembers: ComponentOptions
 declare const theme: {
   Layout: ComponentOptions
   NotFound: ComponentOptions
+  enhanceApp: EnhanceAppContext
 }
 
 export default theme

Rest of the stuff looks fine!

@brc-dd brc-dd merged commit ecf5515 into vuejs:main Sep 1, 2022
brc-dd added a commit that referenced this pull request Sep 9, 2022
brc-dd added a commit that referenced this pull request Sep 9, 2022
@wxsms wxsms deleted the feat/progressbar branch November 17, 2022 03:21
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jan 21, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add a progressbar on top when performing navigation, like VuePress.
2 participants