From 03ea6763e115e960a2576b18a1b11978097d35d3 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 ae68341d1..f76799fff 100644 --- a/packages/client/src/pages/about.vue +++ b/packages/client/src/pages/about.vue @@ -93,8 +93,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 b91330e1b..7af75367b 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 769d9cb2a..8dca559e0 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')), @@ -215,7 +216,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); @@ -240,7 +241,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(() => { // 遷移直後はタイミングによってはコンポーネントが復元し切ってない可能性も考えられるため少し時間を空けて再度スクロール