enhance(client): improve router

Fix #8902
This commit is contained in:
syuilo 2022-06-29 16:00:00 +09:00 committed by Johann150
parent 9ec98e66f9
commit 03ea6763e1
Signed by untrusted user: Johann150
GPG key ID: 9EE6577A2A06F8F1
4 changed files with 22 additions and 4 deletions

View file

@ -8,6 +8,7 @@ type RouteDef = {
component: Component; component: Component;
query?: Record<string, string>; query?: Record<string, string>;
name?: string; name?: string;
hash?: string;
globalCacheKey?: string; globalCacheKey?: string;
}; };
@ -78,7 +79,12 @@ export class Router extends EventEmitter<{
public resolve(path: string): { route: RouteDef; props: Map<string, string>; } | null { public resolve(path: string): { route: RouteDef; props: Map<string, string>; } | null {
let queryString: string | null = null; let queryString: string | null = null;
let hash: string | null = null;
if (path[0] === '/') path = path.substring(1); 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('?')) { if (path.includes('?')) {
queryString = path.substring(path.indexOf('?') + 1); queryString = path.substring(path.indexOf('?') + 1);
path = path.substring(0, path.indexOf('?')); path = path.substring(0, path.indexOf('?'));
@ -127,6 +133,10 @@ export class Router extends EventEmitter<{
if (parts.length !== 0) continue forEachRouteLoop; if (parts.length !== 0) continue forEachRouteLoop;
if (route.hash != null && hash != null) {
props.set(route.hash, hash);
}
if (route.query != null && queryString != null) { if (route.query != null && queryString != null) {
const queryObject = [...new URLSearchParams(queryString).entries()] const queryObject = [...new URLSearchParams(queryString).entries()]
.reduce((obj, entry) => ({ ...obj, [entry[0]]: entry[1] }), {}); .reduce((obj, entry) => ({ ...obj, [entry[0]]: entry[1] }), {});
@ -138,6 +148,7 @@ export class Router extends EventEmitter<{
} }
} }
} }
return { return {
route, route,
props, props,

View file

@ -93,8 +93,14 @@ import number from '@/filters/number';
import { i18n } from '@/i18n'; import { i18n } from '@/i18n';
import { definePageMetadata } from '@/scripts/page-metadata'; import { definePageMetadata } from '@/scripts/page-metadata';
const props = withDefaults(defineProps<{
initialTab?: string;
}>(), {
initialTab: 'overview',
});
let stats = $ref(null); let stats = $ref(null);
let tab = $ref('overview'); let tab = $ref(props.initialTab);
const initStats = () => os.api('stats', { const initStats = () => os.api('stats', {
}).then((res) => { }).then((res) => {

View file

@ -109,7 +109,7 @@ const menuDef = $computed(() => [{
}, { }, {
icon: 'fas fa-globe', icon: 'fas fa-globe',
text: i18n.ts.federation, text: i18n.ts.federation,
to: '/admin/federation', to: '/about#federation',
active: props.initialPage === 'federation', active: props.initialPage === 'federation',
}, { }, {
icon: 'fas fa-clipboard-list', icon: 'fas fa-clipboard-list',

View file

@ -50,6 +50,7 @@ export const routes = [{
}, { }, {
path: '/about', path: '/about',
component: page(() => import('./pages/about.vue')), component: page(() => import('./pages/about.vue')),
hash: 'initialTab',
}, { }, {
path: '/about-misskey', path: '/about-misskey',
component: page(() => import('./pages/about-misskey.vue')), component: page(() => import('./pages/about-misskey.vue')),
@ -215,7 +216,7 @@ export const routes = [{
component: page(() => import('./pages/not-found.vue')), 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); window.history.replaceState({ key: mainRouter.getCurrentKey() }, '', location.href);
@ -240,7 +241,7 @@ mainRouter.addListener('push', ctx => {
}); });
window.addEventListener('popstate', (event) => { 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; const scrollPos = scrollPosStore.get(event.state?.key) ?? 0;
window.scroll({ top: scrollPos, behavior: 'instant' }); window.scroll({ top: scrollPos, behavior: 'instant' });
window.setTimeout(() => { // 遷移直後はタイミングによってはコンポーネントが復元し切ってない可能性も考えられるため少し時間を空けて再度スクロール window.setTimeout(() => { // 遷移直後はタイミングによってはコンポーネントが復元し切ってない可能性も考えられるため少し時間を空けて再度スクロール