From bb68cfaa815ce4b33f0671710fd94f9d94f4324c Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 29 Jun 2022 16:00:00 +0900 Subject: [PATCH] enhance(client): improve router Fix #8902 --- packages/client/src/nirax.ts | 11 +++++++++++ packages/client/src/pages/about.vue | 8 +++++++- packages/client/src/pages/admin/index.vue | 2 +- packages/client/src/router.ts | 5 +++-- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/packages/client/src/nirax.ts b/packages/client/src/nirax.ts index 6db633566..9dc787de4 100644 --- a/packages/client/src/nirax.ts +++ b/packages/client/src/nirax.ts @@ -8,6 +8,7 @@ type RouteDef = { component: Component; query?: Record; name?: string; + hash?: string; globalCacheKey?: string; }; @@ -78,7 +79,12 @@ export class Router extends EventEmitter<{ public resolve(path: string): { route: RouteDef; props: Map; } | null { let queryString: string | null = null; + let hash: string | null = null; if (path[0] === '/') path = path.substring(1); + if (path.includes('#')) { + hash = path.substring(path.indexOf('#') + 1); + path = path.substring(0, path.indexOf('#')); + } if (path.includes('?')) { queryString = path.substring(path.indexOf('?') + 1); path = path.substring(0, path.indexOf('?')); @@ -127,6 +133,10 @@ export class Router extends EventEmitter<{ if (parts.length !== 0) continue forEachRouteLoop; + if (route.hash != null && hash != null) { + props.set(route.hash, hash); + } + if (route.query != null && queryString != null) { const queryObject = [...new URLSearchParams(queryString).entries()] .reduce((obj, entry) => ({ ...obj, [entry[0]]: entry[1] }), {}); @@ -138,6 +148,7 @@ export class Router extends EventEmitter<{ } } } + return { route, props, diff --git a/packages/client/src/pages/about.vue b/packages/client/src/pages/about.vue index de89e3593..683f7446b 100644 --- a/packages/client/src/pages/about.vue +++ b/packages/client/src/pages/about.vue @@ -95,8 +95,14 @@ import number from '@/filters/number'; import { i18n } from '@/i18n'; import { definePageMetadata } from '@/scripts/page-metadata'; +const props = withDefaults(defineProps<{ + initialTab?: string; +}>(), { + initialTab: 'overview', +}); + let stats = $ref(null); -let tab = $ref('overview'); +let tab = $ref(props.initialTab); const initStats = () => os.api('stats', { }).then((res) => { diff --git a/packages/client/src/pages/admin/index.vue b/packages/client/src/pages/admin/index.vue index 5ffbe3495..d967a081b 100644 --- a/packages/client/src/pages/admin/index.vue +++ b/packages/client/src/pages/admin/index.vue @@ -109,7 +109,7 @@ const menuDef = $computed(() => [{ }, { icon: 'fas fa-globe', text: i18n.ts.federation, - to: '/admin/federation', + to: '/about#federation', active: props.initialPage === 'federation', }, { icon: 'fas fa-clipboard-list', diff --git a/packages/client/src/router.ts b/packages/client/src/router.ts index a452a8bb3..d257612f3 100644 --- a/packages/client/src/router.ts +++ b/packages/client/src/router.ts @@ -50,6 +50,7 @@ export const routes = [{ }, { path: '/about', component: page(() => import('./pages/about.vue')), + hash: 'initialTab', }, { path: '/about-misskey', component: page(() => import('./pages/about-misskey.vue')), @@ -203,7 +204,7 @@ export const routes = [{ component: page(() => import('./pages/not-found.vue')), }]; -export const mainRouter = new Router(routes, location.pathname + location.search); +export const mainRouter = new Router(routes, location.pathname + location.search + location.hash); window.history.replaceState({ key: mainRouter.getCurrentKey() }, '', location.href); @@ -228,7 +229,7 @@ mainRouter.addListener('push', ctx => { }); window.addEventListener('popstate', (event) => { - mainRouter.change(location.pathname + location.search, event.state?.key); + mainRouter.change(location.pathname + location.search + location.hash, event.state?.key); const scrollPos = scrollPosStore.get(event.state?.key) ?? 0; window.scroll({ top: scrollPos, behavior: 'instant' }); window.setTimeout(() => { // 遷移直後はタイミングによってはコンポーネントが復元し切ってない可能性も考えられるため少し時間を空けて再度スクロール