refactor(frontend): router refactoring
This commit is contained in:
parent
bdc72e5817
commit
7d4045e8b4
|
@ -15,12 +15,12 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
|
||||
<script lang="ts" setup>
|
||||
import { inject, onBeforeUnmount, provide, ref, shallowRef } from 'vue';
|
||||
import type { IRouter, Resolved } from '@/nirax.js';
|
||||
import type { Router, Resolved } from '@/router.js';
|
||||
import MkLoadingPage from '@/pages/_loading_.vue';
|
||||
import { DI } from '@/di.js';
|
||||
|
||||
const props = defineProps<{
|
||||
router?: IRouter;
|
||||
router?: Router;
|
||||
}>();
|
||||
|
||||
const router = props.router ?? inject(DI.router);
|
||||
|
|
|
@ -22,14 +22,14 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
|
||||
<script lang="ts" setup>
|
||||
import { inject, onBeforeUnmount, provide, ref, shallowRef, computed, nextTick } from 'vue';
|
||||
import type { IRouter, Resolved, RouteDef } from '@/nirax.js';
|
||||
import type { Router, Resolved, RouteDef } from '@/router.js';
|
||||
import { prefer } from '@/preferences.js';
|
||||
import { globalEvents } from '@/events.js';
|
||||
import MkLoadingPage from '@/pages/_loading_.vue';
|
||||
import { DI } from '@/di.js';
|
||||
|
||||
const props = defineProps<{
|
||||
router?: IRouter;
|
||||
router?: Router;
|
||||
}>();
|
||||
|
||||
const router = props.router ?? inject(DI.router);
|
||||
|
|
|
@ -42,7 +42,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
|
||||
<script lang="ts" setup>
|
||||
import { inject, onBeforeUnmount, provide, ref, shallowRef, computed, nextTick } from 'vue';
|
||||
import type { IRouter, Resolved, RouteDef } from '@/nirax.js';
|
||||
import type { Router, Resolved, RouteDef } from '@/router.js';
|
||||
import { prefer } from '@/preferences.js';
|
||||
import { globalEvents } from '@/events.js';
|
||||
import MkLoadingPage from '@/pages/_loading_.vue';
|
||||
|
@ -50,7 +50,7 @@ import { DI } from '@/di.js';
|
|||
import { deepEqual } from '@/utility/deep-equal.js';
|
||||
|
||||
const props = defineProps<{
|
||||
router?: IRouter;
|
||||
router?: Router;
|
||||
}>();
|
||||
|
||||
const router = props.router ?? inject(DI.router);
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
*/
|
||||
|
||||
import type { InjectionKey, Ref } from 'vue';
|
||||
import type { IRouter } from '@/nirax.js';
|
||||
import type { Router } from '@/router.js';
|
||||
|
||||
export const DI = {
|
||||
routerCurrentDepth: Symbol() as InjectionKey<number>,
|
||||
router: Symbol() as InjectionKey<IRouter>,
|
||||
router: Symbol() as InjectionKey<Router>,
|
||||
mock: Symbol() as InjectionKey<boolean>,
|
||||
pageMetadata: Symbol() as InjectionKey<Ref<Record<string, any>>>,
|
||||
};
|
||||
|
|
|
@ -103,88 +103,7 @@ function parsePath(path: string): ParsedPath {
|
|||
return res;
|
||||
}
|
||||
|
||||
export interface IRouter extends EventEmitter<RouterEvent> {
|
||||
current: Resolved;
|
||||
currentRef: ShallowRef<Resolved>;
|
||||
currentRoute: ShallowRef<RouteDef>;
|
||||
navHook: ((path: string, flag?: RouterFlag) => boolean) | null;
|
||||
|
||||
/**
|
||||
* ルートの初期化(eventListenerの定義後に必ず呼び出すこと)
|
||||
*/
|
||||
init(): void;
|
||||
|
||||
resolve(path: string): Resolved | null;
|
||||
|
||||
getCurrentPath(): string;
|
||||
|
||||
push(path: string, flag?: RouterFlag): void;
|
||||
|
||||
replace(path: string): void;
|
||||
|
||||
/** @see EventEmitter */
|
||||
eventNames(): Array<EventEmitter.EventNames<RouterEvent>>;
|
||||
|
||||
/** @see EventEmitter */
|
||||
listeners<T extends EventEmitter.EventNames<RouterEvent>>(
|
||||
event: T
|
||||
): Array<EventEmitter.EventListener<RouterEvent, T>>;
|
||||
|
||||
/** @see EventEmitter */
|
||||
listenerCount(
|
||||
event: EventEmitter.EventNames<RouterEvent>
|
||||
): number;
|
||||
|
||||
/** @see EventEmitter */
|
||||
emit<T extends EventEmitter.EventNames<RouterEvent>>(
|
||||
event: T,
|
||||
...args: EventEmitter.EventArgs<RouterEvent, T>
|
||||
): boolean;
|
||||
|
||||
/** @see EventEmitter */
|
||||
on<T extends EventEmitter.EventNames<RouterEvent>>(
|
||||
event: T,
|
||||
fn: EventEmitter.EventListener<RouterEvent, T>,
|
||||
context?: any
|
||||
): this;
|
||||
|
||||
/** @see EventEmitter */
|
||||
addListener<T extends EventEmitter.EventNames<RouterEvent>>(
|
||||
event: T,
|
||||
fn: EventEmitter.EventListener<RouterEvent, T>,
|
||||
context?: any
|
||||
): this;
|
||||
|
||||
/** @see EventEmitter */
|
||||
once<T extends EventEmitter.EventNames<RouterEvent>>(
|
||||
event: T,
|
||||
fn: EventEmitter.EventListener<RouterEvent, T>,
|
||||
context?: any
|
||||
): this;
|
||||
|
||||
/** @see EventEmitter */
|
||||
removeListener<T extends EventEmitter.EventNames<RouterEvent>>(
|
||||
event: T,
|
||||
fn?: EventEmitter.EventListener<RouterEvent, T>,
|
||||
context?: any,
|
||||
once?: boolean | undefined
|
||||
): this;
|
||||
|
||||
/** @see EventEmitter */
|
||||
off<T extends EventEmitter.EventNames<RouterEvent>>(
|
||||
event: T,
|
||||
fn?: EventEmitter.EventListener<RouterEvent, T>,
|
||||
context?: any,
|
||||
once?: boolean | undefined
|
||||
): this;
|
||||
|
||||
/** @see EventEmitter */
|
||||
removeAllListeners(
|
||||
event?: EventEmitter.EventNames<RouterEvent>
|
||||
): this;
|
||||
}
|
||||
|
||||
export class Router extends EventEmitter<RouterEvent> implements IRouter {
|
||||
export class Router extends EventEmitter<RouterEvent> {
|
||||
private routes: RouteDef[];
|
||||
public current: Resolved;
|
||||
public currentRef: ShallowRef<Resolved>;
|
||||
|
@ -367,7 +286,6 @@ export class Router extends EventEmitter<RouterEvent> implements IRouter {
|
|||
res.props.set('showLoginPopup', true);
|
||||
}
|
||||
|
||||
const isSamePath = beforePath === path;
|
||||
this.current = res;
|
||||
this.currentRef.value = res;
|
||||
this.currentRoute.value = res.route;
|
|
@ -5,8 +5,8 @@
|
|||
|
||||
import { defineAsyncComponent } from 'vue';
|
||||
import type { AsyncComponentLoader } from 'vue';
|
||||
import type { IRouter, RouteDef } from '@/nirax.js';
|
||||
import { Router } from '@/nirax.js';
|
||||
import type { RouteDef } from '@/router.js';
|
||||
import { Router } from '@/router.js';
|
||||
import { $i, iAmModerator } from '@/i.js';
|
||||
import MkLoading from '@/pages/_loading_.vue';
|
||||
import MkError from '@/pages/_error_.vue';
|
||||
|
@ -578,6 +578,6 @@ const routes: RouteDef[] = [{
|
|||
component: page(() => import('@/pages/not-found.vue')),
|
||||
}];
|
||||
|
||||
export function createMainRouter(path: string): IRouter {
|
||||
export function createMainRouter(path: string): Router {
|
||||
return new Router(routes, path, !!$i, page(() => import('@/pages/not-found.vue')));
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*/
|
||||
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
import type { IRouter, Resolved, RouteDef, RouterEvent, RouterFlag } from '@/nirax.js';
|
||||
import type { Router, Resolved, RouteDef, RouterEvent, RouterFlag } from '@/router.js';
|
||||
|
||||
import type { App, ShallowRef } from 'vue';
|
||||
import { analytics } from '@/analytics.js';
|
||||
|
@ -13,7 +13,7 @@ import { analytics } from '@/analytics.js';
|
|||
* {@link Router}による画面遷移を可能とするために{@link mainRouter}をセットアップする。
|
||||
* また、{@link Router}のインスタンスを作成するためのファクトリも{@link provide}経由で公開する(`routerFactory`というキーで取得可能)
|
||||
*/
|
||||
export function setupRouter(app: App, routerFactory: ((path: string) => IRouter)): void {
|
||||
export function setupRouter(app: App, routerFactory: ((path: string) => Router)): void {
|
||||
app.provide('routerFactory', routerFactory);
|
||||
|
||||
const mainRouter = routerFactory(location.pathname + location.search + location.hash);
|
||||
|
@ -43,7 +43,7 @@ export function setupRouter(app: App, routerFactory: ((path: string) => IRouter)
|
|||
setMainRouter(mainRouter);
|
||||
}
|
||||
|
||||
function getMainRouter(): IRouter {
|
||||
function getMainRouter(): Router {
|
||||
const router = mainRouterHolder;
|
||||
if (!router) {
|
||||
throw new Error('mainRouter is not found.');
|
||||
|
@ -56,7 +56,7 @@ function getMainRouter(): IRouter {
|
|||
* メインルータを設定する。一度設定すると、それ以降は変更できない。
|
||||
* {@link setupRouter}から呼び出されることのみを想定している。
|
||||
*/
|
||||
export function setMainRouter(router: IRouter) {
|
||||
export function setMainRouter(router: Router) {
|
||||
if (mainRouterHolder) {
|
||||
throw new Error('mainRouter is already exists.');
|
||||
}
|
||||
|
@ -69,10 +69,10 @@ export function setMainRouter(router: IRouter) {
|
|||
* {@link mainRouter}は起動シーケンスの一部にて初期化されるため、僅かにundefinedになる期間がある。
|
||||
* その僅かな期間のためだけに型をundefined込みにしたくないのでこのクラスを緩衝材として使用する。
|
||||
*/
|
||||
class MainRouterProxy implements IRouter {
|
||||
private supplier: () => IRouter;
|
||||
class MainRouterProxy implements Router {
|
||||
private supplier: () => Router;
|
||||
|
||||
constructor(supplier: () => IRouter) {
|
||||
constructor(supplier: () => Router) {
|
||||
this.supplier = supplier;
|
||||
}
|
||||
|
||||
|
@ -194,6 +194,6 @@ class MainRouterProxy implements IRouter {
|
|||
}
|
||||
}
|
||||
|
||||
let mainRouterHolder: IRouter | null = null;
|
||||
let mainRouterHolder: Router | null = null;
|
||||
|
||||
export const mainRouter: IRouter = new MainRouterProxy(getMainRouter);
|
||||
export const mainRouter: Router = new MainRouterProxy(getMainRouter);
|
||||
|
|
|
@ -4,15 +4,15 @@
|
|||
*/
|
||||
|
||||
import { inject } from 'vue';
|
||||
import type { IRouter } from '@/nirax.js';
|
||||
import type { Router } from '@/router.js';
|
||||
import { mainRouter } from '@/router/main.js';
|
||||
import { DI } from '@/di.js';
|
||||
|
||||
/**
|
||||
* メインの{@link Router}を取得する。
|
||||
* あらかじめ{@link setupRouter}を実行しておく必要がある({@link provide}により{@link IRouter}のインスタンスを注入可能であるならばこの限りではない)
|
||||
* あらかじめ{@link setupRouter}を実行しておく必要がある({@link provide}により{@link Router}のインスタンスを注入可能であるならばこの限りではない)
|
||||
*/
|
||||
export function useRouter(): IRouter {
|
||||
export function useRouter(): Router {
|
||||
return inject(DI.router, null) ?? mainRouter;
|
||||
}
|
||||
|
||||
|
@ -20,8 +20,8 @@ export function useRouter(): IRouter {
|
|||
* 任意の{@link Router}を取得するためのファクトリを取得する。
|
||||
* あらかじめ{@link setupRouter}を実行しておく必要がある。
|
||||
*/
|
||||
export function useRouterFactory(): (path: string) => IRouter {
|
||||
const factory = inject<(path: string) => IRouter>('routerFactory');
|
||||
export function useRouterFactory(): (path: string) => Router {
|
||||
const factory = inject<(path: string) => Router>('routerFactory');
|
||||
if (!factory) {
|
||||
console.error('routerFactory is not defined.');
|
||||
throw new Error('routerFactory is not defined.');
|
||||
|
|
|
@ -7,7 +7,7 @@ import { toUnicode } from 'punycode.js';
|
|||
import { defineAsyncComponent, ref, watch } from 'vue';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import { host, url } from '@@/js/config.js';
|
||||
import type { IRouter } from '@/nirax.js';
|
||||
import type { Router } from '@/router.js';
|
||||
import type { MenuItem } from '@/types/menu.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { copyToClipboard } from '@/utility/copy-to-clipboard.js';
|
||||
|
@ -21,7 +21,7 @@ import { genEmbedCode } from '@/utility/get-embed-code.js';
|
|||
import { prefer } from '@/preferences.js';
|
||||
import { getPluginHandlers } from '@/plugin.js';
|
||||
|
||||
export function getUserMenu(user: Misskey.entities.UserDetailed, router: IRouter = mainRouter) {
|
||||
export function getUserMenu(user: Misskey.entities.UserDetailed, router: Router = mainRouter) {
|
||||
const meId = $i ? $i.id : null;
|
||||
|
||||
const cleanups = [] as (() => void)[];
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
import * as os from '@/os.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { Router } from '@/nirax.js';
|
||||
import { Router } from '@/router.js';
|
||||
import { mainRouter } from '@/router/main.js';
|
||||
|
||||
export async function lookup(router?: Router) {
|
||||
|
|
Loading…
Reference in New Issue