summaryrefslogtreecommitdiff
path: root/packages/frontend/src/nirax.ts
diff options
context:
space:
mode:
authorsyuilo <Syuilotan@yahoo.co.jp>2023-07-21 20:36:07 +0900
committerGitHub <noreply@github.com>2023-07-21 20:36:07 +0900
commite64a81aa1d2801516e8eac8dc69aac540489f20b (patch)
tree56accbc0f5f71db864e1e975920135fb0a957291 /packages/frontend/src/nirax.ts
parentMerge pull request #10990 from misskey-dev/develop (diff)
parentNew Crowdin updates (#11336) (diff)
downloadmisskey-e64a81aa1d2801516e8eac8dc69aac540489f20b.tar.gz
misskey-e64a81aa1d2801516e8eac8dc69aac540489f20b.tar.bz2
misskey-e64a81aa1d2801516e8eac8dc69aac540489f20b.zip
Merge pull request #11301 from misskey-dev/develop
Release: 13.14.0
Diffstat (limited to 'packages/frontend/src/nirax.ts')
-rw-r--r--packages/frontend/src/nirax.ts56
1 files changed, 40 insertions, 16 deletions
diff --git a/packages/frontend/src/nirax.ts b/packages/frontend/src/nirax.ts
index 68977ed796..3a03444de2 100644
--- a/packages/frontend/src/nirax.ts
+++ b/packages/frontend/src/nirax.ts
@@ -1,8 +1,7 @@
// NIRAX --- A lightweight router
import { EventEmitter } from 'eventemitter3';
-import { Component, shallowRef, ShallowRef } from 'vue';
-import { pleaseLogin } from '@/scripts/please-login';
+import { Component, onMounted, shallowRef, ShallowRef } from 'vue';
import { safeURIDecode } from '@/scripts/safe-uri-decode';
type RouteDef = {
@@ -23,7 +22,7 @@ type ParsedPath = (string | {
optional?: boolean;
})[];
-export type Resolved = { route: RouteDef; props: Map<string, string>; child?: Resolved; };
+export type Resolved = { route: RouteDef; props: Map<string, string | boolean>; child?: Resolved; };
function parsePath(path: string): ParsedPath {
const res = [] as ParsedPath;
@@ -75,15 +74,19 @@ export class Router extends EventEmitter<{
public currentRef: ShallowRef<Resolved> = shallowRef();
public currentRoute: ShallowRef<RouteDef> = shallowRef();
private currentPath: string;
+ private isLoggedIn: boolean;
+ private notFoundPageComponent: Component;
private currentKey = Date.now().toString();
public navHook: ((path: string, flag?: any) => boolean) | null = null;
- constructor(routes: Router['routes'], currentPath: Router['currentPath']) {
+ constructor(routes: Router['routes'], currentPath: Router['currentPath'], isLoggedIn: boolean, notFoundPageComponent: Component) {
super();
this.routes = routes;
this.currentPath = currentPath;
+ this.isLoggedIn = isLoggedIn;
+ this.notFoundPageComponent = notFoundPageComponent;
this.navigate(currentPath, null, false);
}
@@ -159,11 +162,11 @@ export class Router extends EventEmitter<{
if (route.hash != null && hash != null) {
props.set(route.hash, safeURIDecode(hash));
}
-
+
if (route.query != null && queryString != null) {
const queryObject = [...new URLSearchParams(queryString).entries()]
.reduce((obj, entry) => ({ ...obj, [entry[0]]: entry[1] }), {});
-
+
for (const q in route.query) {
const as = route.query[q];
if (queryObject[q]) {
@@ -171,7 +174,7 @@ export class Router extends EventEmitter<{
}
}
}
-
+
return {
route,
props,
@@ -212,8 +215,9 @@ export class Router extends EventEmitter<{
throw new Error('no route found for: ' + path);
}
- if (res.route.loginRequired) {
- pleaseLogin('/');
+ if (res.route.loginRequired && !this.isLoggedIn) {
+ res.route.component = this.notFoundPageComponent;
+ res.props.set('showLoginPopup', true);
}
const isSamePath = beforePath === path;
@@ -263,13 +267,33 @@ export class Router extends EventEmitter<{
});
}
- public replace(path: string, key?: string | null, emitEvent = true) {
+ public replace(path: string, key?: string | null) {
this.navigate(path, key);
- if (emitEvent) {
- this.emit('replace', {
- path,
- key: this.currentKey,
- });
- }
}
}
+
+export function useScrollPositionManager(getScrollContainer: () => HTMLElement, router: Router) {
+ const scrollPosStore = new Map<string, number>();
+
+ onMounted(() => {
+ const scrollContainer = getScrollContainer();
+
+ scrollContainer.addEventListener('scroll', () => {
+ scrollPosStore.set(router.getCurrentKey(), scrollContainer.scrollTop);
+ }, { passive: true });
+
+ router.addListener('change', ctx => {
+ const scrollPos = scrollPosStore.get(ctx.key) ?? 0;
+ scrollContainer.scroll({ top: scrollPos, behavior: 'instant' });
+ if (scrollPos !== 0) {
+ window.setTimeout(() => { // 遷移直後はタイミングによってはコンポーネントが復元し切ってない可能性も考えられるため少し時間を空けて再度スクロール
+ scrollContainer.scroll({ top: scrollPos, behavior: 'instant' });
+ }, 100);
+ }
+ });
+
+ router.addListener('same', () => {
+ scrollContainer.scroll({ top: 0, behavior: 'smooth' });
+ });
+ });
+}