@allbluecn/web-app 0.4.22 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +12 -8
- package/src/components/knowledge/knowledge-toolbar.tsx +124 -1
- package/src/components/layout/sidebar-03/app-sidebar.tsx +3 -4
- package/src/components/layout/sidebar-03/nav-notifications.tsx +135 -52
- package/src/components/layout/sidebar-03/user-menu.tsx +4 -2
- package/src/components/notifications/settings-notifications.tsx +198 -0
- package/src/components/notifications/team-notifications.tsx +343 -0
- package/src/components/settings/personal-team/team/team-client.tsx +51 -12
- package/src/components/settings/personal-team/team/team-invitations.tsx +181 -181
- package/src/components/shared/wave-physics-loader.tsx +155 -0
- package/src/components/story/__tests__/dependency-type-badge.test.ts +89 -0
- package/src/components/story/constants.ts +124 -51
- package/src/components/story/create-story-dialog.tsx +12 -6
- package/src/components/story/detail/__tests__/associated-attachments-panel.test.tsx +114 -0
- package/src/components/story/detail/activity-timeline.tsx +15 -0
- package/src/components/story/detail/story-detail-body.tsx +14 -3
- package/src/components/story/detail/story-detail-toolbar/associated-attachments-panel.tsx +748 -0
- package/src/components/story/detail/story-detail-toolbar/categories.tsx +23 -18
- package/src/components/story/detail/story-detail-toolbar/children.tsx +51 -274
- package/src/components/story/detail/story-detail-toolbar/dependencies.tsx +13 -45
- package/src/components/story/detail/story-detail-toolbar/dependency-panel.tsx +473 -0
- package/src/components/story/detail/story-detail-toolbar.tsx +237 -10
- package/src/components/story/display/__tests__/use-paged-story-groups.test.ts +152 -1
- package/src/components/story/display/use-paged-story-groups.ts +370 -28
- package/src/components/story/inline-editors/story-select-dialog.tsx +107 -16
- package/src/components/story/peek-panel.tsx +8 -1
- package/src/components/story/relations/__tests__/attachment-manage-dialog.test.tsx +171 -0
- package/src/components/story/relations/__tests__/knowledge-select-dialog.test.tsx +174 -0
- package/src/components/story/relations/__tests__/link-manage-dialog.test.tsx +93 -0
- package/src/components/story/relations/attachment-manage-dialog.tsx +490 -0
- package/src/components/story/relations/file-preview.tsx +173 -0
- package/src/components/story/relations/format.ts +120 -0
- package/src/{config/sidebar-notifications.ts → components/story/relations/general-groups.ts} +12 -30
- package/src/components/story/relations/knowledge-select-dialog.tsx +403 -0
- package/src/components/story/relations/link-manage-dialog.tsx +191 -0
- package/src/components/story/relations/story-ref-row.tsx +319 -0
- package/src/components/story/story-list-view.tsx +3 -1
- package/src/components/story/story-panel-header.tsx +4 -1
- package/src/components/story/types.ts +30 -18
- package/src/components/story/views/story-list/batch-toolbar.tsx +12 -1
- package/src/components/story/views/story-list/index.tsx +16 -5
- package/src/components/story/views/story-list/row.tsx +5 -4
- package/src/components/ui/separator.tsx +1 -1
- package/src/hooks/use-notifications.ts +4 -1
- package/src/lib/__tests__/datetime.test.ts +16 -1
- package/src/lib/changelog/sdk-versions.ts +19 -19
- package/src/lib/datetime.ts +1 -0
- package/src/lib/story/__tests__/video-embed.test.ts +77 -0
- package/src/lib/story/video-embed.ts +59 -0
- package/src/routeTree.gen.ts +65 -0
- package/src/routes/_nav/notifications/route.lazy.tsx +22 -0
- package/src/routes/_nav/notifications/route.tsx +30 -0
- package/src/routes/_nav/projects/$projectId/settings/route.lazy.tsx +74 -3
- package/src/routes/_nav/projects/$projectId/settings/route.tsx +6 -2
- package/src/routes/_nav/settings/notifications/route.lazy.tsx +6 -5
- package/src/routes/api/attachments/$id/content.ts +60 -0
- package/src/routes/api/attachments/upload.ts +148 -0
- package/src/routes/api/notifications/stream.ts +4 -0
- package/src/server/notifications/__tests__/notification-service.test.ts +189 -0
- package/src/server/notifications/notification-service.ts +137 -27
- package/src/server/serverFns/__tests__/project-kb.test.ts +147 -0
- package/src/server/serverFns/__tests__/team-invitation.test.ts +73 -7
- package/src/server/serverFns/__tests__/team-join-request.test.ts +5 -3
- package/src/server/serverFns/knowledge.ts +50 -4
- package/src/server/serverFns/locale.ts +15 -3
- package/src/server/serverFns/notifications.ts +18 -4
- package/src/server/serverFns/project.ts +43 -0
- package/src/server/serverFns/story/__tests__/kb-scope.test.ts +56 -0
- package/src/server/serverFns/story/__tests__/story-assoc.test.ts +222 -0
- package/src/server/serverFns/story/__tests__/story-dependencies.test.ts +265 -0
- package/src/server/serverFns/story/__tests__/story-groups.test.ts +19 -1
- package/src/server/serverFns/story/index.ts +7 -6
- package/src/server/serverFns/story/kb-general.ts +39 -0
- package/src/server/serverFns/story/kb-scope.ts +52 -0
- package/src/server/serverFns/story/link-preview.ts +115 -0
- package/src/server/serverFns/story/story-assoc.ts +339 -50
- package/src/server/serverFns/story/story-attachments.ts +12 -43
- package/src/server/serverFns/story/story-crud.ts +21 -4
- package/src/server/serverFns/story/story-dependencies.ts +138 -162
- package/src/server/serverFns/story/story-groups.ts +23 -3
- package/src/server/serverFns/story/story-links.ts +13 -1
- package/src/server/serverFns/story/story-transfer.ts +5 -3
- package/src/server/serverFns/story/story-tree.ts +28 -1
- package/src/server/serverFns/story/types.ts +37 -0
- package/src/server/serverFns/team.ts +51 -2
- package/src/styles/globals.css +25 -0
- package/vite.shared.ts +2 -0
- package/src/components/notifications/notification-list.tsx +0 -232
- package/src/components/notifications/notification-preferences.tsx +0 -156
- package/src/components/story/detail/story-detail-toolbar/attachments.tsx +0 -73
- package/src/components/story/detail/story-detail-toolbar/knowledge.tsx +0 -73
- package/src/components/story/detail/story-detail-toolbar/links.tsx +0 -73
- package/src/components/story/relation-badge.tsx +0 -57
- package/src/components/story/relations/attachments-panel.tsx +0 -179
- package/src/components/story/relations/dependency-panel.tsx +0 -190
- package/src/components/story/relations/hierarchy-panel.tsx +0 -180
- package/src/components/story/relations/knowledge-panel.tsx +0 -284
- package/src/components/story/relations/links-panel.tsx +0 -240
- package/src/components/story/relations/tab.tsx +0 -212
|
@@ -10,7 +10,7 @@ export const SDK_GROUPS: SdkGroup[] = [
|
|
|
10
10
|
"name": "@tanstack/react-start",
|
|
11
11
|
"displayName": "TanStack Start",
|
|
12
12
|
"version": "v1.168.49",
|
|
13
|
-
"lastUpdate": "
|
|
13
|
+
"lastUpdate": "Sep 1, 2026",
|
|
14
14
|
"source": "apps/web/package.json#dependencies",
|
|
15
15
|
"docsUrl": "https://tanstack.com/start/latest"
|
|
16
16
|
},
|
|
@@ -18,7 +18,7 @@ export const SDK_GROUPS: SdkGroup[] = [
|
|
|
18
18
|
"name": "@tanstack/react-router",
|
|
19
19
|
"displayName": "TanStack Router",
|
|
20
20
|
"version": "v1.170.32",
|
|
21
|
-
"lastUpdate": "
|
|
21
|
+
"lastUpdate": "Sep 1, 2026",
|
|
22
22
|
"source": "apps/web/package.json#dependencies",
|
|
23
23
|
"docsUrl": "https://tanstack.com/router/latest"
|
|
24
24
|
},
|
|
@@ -26,7 +26,7 @@ export const SDK_GROUPS: SdkGroup[] = [
|
|
|
26
26
|
"name": "@tanstack/react-query",
|
|
27
27
|
"displayName": "TanStack Query",
|
|
28
28
|
"version": "v5.102.8",
|
|
29
|
-
"lastUpdate": "
|
|
29
|
+
"lastUpdate": "Sep 1, 2026",
|
|
30
30
|
"source": "apps/web/package.json#dependencies",
|
|
31
31
|
"docsUrl": "https://tanstack.com/query/latest"
|
|
32
32
|
},
|
|
@@ -34,7 +34,7 @@ export const SDK_GROUPS: SdkGroup[] = [
|
|
|
34
34
|
"name": "@tanstack/ai",
|
|
35
35
|
"displayName": "TanStack AI",
|
|
36
36
|
"version": "v0.52.0",
|
|
37
|
-
"lastUpdate": "
|
|
37
|
+
"lastUpdate": "Sep 1, 2026",
|
|
38
38
|
"source": "apps/web/package.json#dependencies",
|
|
39
39
|
"docsUrl": "https://tanstack.com/ai/latest"
|
|
40
40
|
},
|
|
@@ -42,7 +42,7 @@ export const SDK_GROUPS: SdkGroup[] = [
|
|
|
42
42
|
"name": "@tanstack/react-table",
|
|
43
43
|
"displayName": "TanStack Table",
|
|
44
44
|
"version": "v9.2.3",
|
|
45
|
-
"lastUpdate": "
|
|
45
|
+
"lastUpdate": "Sep 1, 2026",
|
|
46
46
|
"source": "apps/web/package.json#dependencies",
|
|
47
47
|
"docsUrl": "https://tanstack.com/table/latest"
|
|
48
48
|
},
|
|
@@ -50,7 +50,7 @@ export const SDK_GROUPS: SdkGroup[] = [
|
|
|
50
50
|
"name": "@tanstack/react-form",
|
|
51
51
|
"displayName": "TanStack Form",
|
|
52
52
|
"version": "v2.0.0-alpha.2",
|
|
53
|
-
"lastUpdate": "
|
|
53
|
+
"lastUpdate": "Sep 1, 2026",
|
|
54
54
|
"source": "apps/web/package.json#dependencies",
|
|
55
55
|
"docsUrl": "https://tanstack.com/form/latest"
|
|
56
56
|
},
|
|
@@ -58,7 +58,7 @@ export const SDK_GROUPS: SdkGroup[] = [
|
|
|
58
58
|
"name": "@tanstack/charts",
|
|
59
59
|
"displayName": "TanStack Charts",
|
|
60
60
|
"version": "v0.16.0",
|
|
61
|
-
"lastUpdate": "
|
|
61
|
+
"lastUpdate": "Sep 1, 2026",
|
|
62
62
|
"source": "apps/admin/package.json#dependencies",
|
|
63
63
|
"docsUrl": "https://tanstack.com/charts/latest"
|
|
64
64
|
},
|
|
@@ -66,7 +66,7 @@ export const SDK_GROUPS: SdkGroup[] = [
|
|
|
66
66
|
"name": "@tanstack/react-pacer",
|
|
67
67
|
"displayName": "TanStack Pacer",
|
|
68
68
|
"version": "v0.23.0",
|
|
69
|
-
"lastUpdate": "
|
|
69
|
+
"lastUpdate": "Sep 1, 2026",
|
|
70
70
|
"source": "apps/web/package.json#dependencies",
|
|
71
71
|
"docsUrl": "https://tanstack.com/pacer/latest"
|
|
72
72
|
},
|
|
@@ -74,7 +74,7 @@ export const SDK_GROUPS: SdkGroup[] = [
|
|
|
74
74
|
"name": "@tanstack/react-hotkeys",
|
|
75
75
|
"displayName": "TanStack Hotkeys",
|
|
76
76
|
"version": "v0.10.0",
|
|
77
|
-
"lastUpdate": "
|
|
77
|
+
"lastUpdate": "Sep 1, 2026",
|
|
78
78
|
"source": "apps/web/package.json#dependencies",
|
|
79
79
|
"docsUrl": "https://tanstack.com/hotkeys/latest"
|
|
80
80
|
},
|
|
@@ -82,7 +82,7 @@ export const SDK_GROUPS: SdkGroup[] = [
|
|
|
82
82
|
"name": "@tanstack/react-virtual",
|
|
83
83
|
"displayName": "TanStack Virtual",
|
|
84
84
|
"version": "v3.14.10",
|
|
85
|
-
"lastUpdate": "
|
|
85
|
+
"lastUpdate": "Sep 1, 2026",
|
|
86
86
|
"source": "apps/admin/package.json#dependencies",
|
|
87
87
|
"docsUrl": "https://tanstack.com/virtual/latest"
|
|
88
88
|
}
|
|
@@ -95,15 +95,15 @@ export const SDK_GROUPS: SdkGroup[] = [
|
|
|
95
95
|
"items": [
|
|
96
96
|
{
|
|
97
97
|
"name": "@allbluecn/web-app",
|
|
98
|
-
"version": "v0.
|
|
99
|
-
"lastUpdate": "
|
|
98
|
+
"version": "v0.5.1",
|
|
99
|
+
"lastUpdate": "Sep 1, 2026",
|
|
100
100
|
"source": "apps/web/package.json",
|
|
101
101
|
"docsUrl": "https://github.com/allbluecn/allblue"
|
|
102
102
|
},
|
|
103
103
|
{
|
|
104
104
|
"name": "@allbluecn/kernel",
|
|
105
105
|
"version": "v0.3.1",
|
|
106
|
-
"lastUpdate": "
|
|
106
|
+
"lastUpdate": "Sep 1, 2026",
|
|
107
107
|
"source": "packages/kernel/package.json",
|
|
108
108
|
"docsUrl": "https://github.com/allbluecn/allblue"
|
|
109
109
|
}
|
|
@@ -117,42 +117,42 @@ export const SDK_GROUPS: SdkGroup[] = [
|
|
|
117
117
|
{
|
|
118
118
|
"name": "Vite",
|
|
119
119
|
"version": "v8.1.5",
|
|
120
|
-
"lastUpdate": "
|
|
120
|
+
"lastUpdate": "Sep 1, 2026",
|
|
121
121
|
"source": "apps/web/package.json#devDependencies",
|
|
122
122
|
"docsUrl": "https://vite.dev/"
|
|
123
123
|
},
|
|
124
124
|
{
|
|
125
125
|
"name": "Node.js",
|
|
126
126
|
"version": "v24.19.0",
|
|
127
|
-
"lastUpdate": "
|
|
127
|
+
"lastUpdate": "Sep 1, 2026",
|
|
128
128
|
"source": ".nvmrc",
|
|
129
129
|
"docsUrl": "https://nodejs.org/"
|
|
130
130
|
},
|
|
131
131
|
{
|
|
132
132
|
"name": "Prisma",
|
|
133
133
|
"version": "v7.8.0",
|
|
134
|
-
"lastUpdate": "
|
|
134
|
+
"lastUpdate": "Sep 1, 2026",
|
|
135
135
|
"source": "packages/database/package.json#devDependencies",
|
|
136
136
|
"docsUrl": "https://www.prisma.io/docs"
|
|
137
137
|
},
|
|
138
138
|
{
|
|
139
139
|
"name": "shadcn UI",
|
|
140
140
|
"version": "v1.2.4",
|
|
141
|
-
"lastUpdate": "
|
|
141
|
+
"lastUpdate": "Sep 1, 2026",
|
|
142
142
|
"source": "apps/web/package.json#dependencies",
|
|
143
143
|
"docsUrl": "https://ui.shadcn.com/"
|
|
144
144
|
},
|
|
145
145
|
{
|
|
146
146
|
"name": "TipTap",
|
|
147
147
|
"version": "v3.27.4",
|
|
148
|
-
"lastUpdate": "
|
|
148
|
+
"lastUpdate": "Sep 1, 2026",
|
|
149
149
|
"source": "packages/shared/package.json#devDependencies",
|
|
150
150
|
"docsUrl": "https://tiptap.dev/"
|
|
151
151
|
},
|
|
152
152
|
{
|
|
153
153
|
"name": "Lucide React",
|
|
154
154
|
"version": "v1.24.0",
|
|
155
|
-
"lastUpdate": "
|
|
155
|
+
"lastUpdate": "Sep 1, 2026",
|
|
156
156
|
"source": "packages/ui/package.json#dependencies",
|
|
157
157
|
"docsUrl": "https://lucide.dev/"
|
|
158
158
|
}
|
package/src/lib/datetime.ts
CHANGED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { resolveVideoEmbed } from "../video-embed";
|
|
3
|
+
|
|
4
|
+
describe("resolveVideoEmbed", () => {
|
|
5
|
+
it("非视频链接返回 null", () => {
|
|
6
|
+
expect(resolveVideoEmbed("https://example.com/page")).toBeNull();
|
|
7
|
+
expect(resolveVideoEmbed("https://lucide.dev/icons/layout-list")).toBeNull();
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it("直链视频文件走 file 分支(忽略 query/hash)", () => {
|
|
11
|
+
expect(resolveVideoEmbed("https://cdn.example.com/a.mp4")).toEqual({
|
|
12
|
+
kind: "file",
|
|
13
|
+
src: "https://cdn.example.com/a.mp4",
|
|
14
|
+
});
|
|
15
|
+
expect(
|
|
16
|
+
resolveVideoEmbed("https://cdn.example.com/a.webm?token=x#t=1"),
|
|
17
|
+
).toEqual({ kind: "file", src: "https://cdn.example.com/a.webm?token=x#t=1" });
|
|
18
|
+
expect(resolveVideoEmbed("https://cdn.example.com/a.MOV")).toEqual({
|
|
19
|
+
kind: "file",
|
|
20
|
+
src: "https://cdn.example.com/a.MOV",
|
|
21
|
+
});
|
|
22
|
+
// 扩展名仅匹配路径末段,不匹配 query 里的伪扩展名
|
|
23
|
+
expect(resolveVideoEmbed("https://example.com/watch?file=a.mp4")).toBeNull();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("YouTube watch 页转换为 embed 播放器", () => {
|
|
27
|
+
expect(resolveVideoEmbed("https://www.youtube.com/watch?v=dQw4w9WgXcQ")).toEqual({
|
|
28
|
+
kind: "iframe",
|
|
29
|
+
src: "https://www.youtube.com/embed/dQw4w9WgXcQ",
|
|
30
|
+
});
|
|
31
|
+
expect(
|
|
32
|
+
resolveVideoEmbed("https://www.youtube.com/watch?v=dQw4w9WgXcQ&t=30s"),
|
|
33
|
+
).toEqual({ kind: "iframe", src: "https://www.youtube.com/embed/dQw4w9WgXcQ" });
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("YouTube youtu.be 短链与 shorts 转换", () => {
|
|
37
|
+
expect(resolveVideoEmbed("https://youtu.be/dQw4w9WgXcQ")).toEqual({
|
|
38
|
+
kind: "iframe",
|
|
39
|
+
src: "https://www.youtube.com/embed/dQw4w9WgXcQ",
|
|
40
|
+
});
|
|
41
|
+
expect(resolveVideoEmbed("https://www.youtube.com/shorts/abc123")).toEqual({
|
|
42
|
+
kind: "iframe",
|
|
43
|
+
src: "https://www.youtube.com/embed/abc123",
|
|
44
|
+
});
|
|
45
|
+
// 已是 embed 链接原样返回
|
|
46
|
+
expect(resolveVideoEmbed("https://www.youtube.com/embed/dQw4w9WgXcQ")).toEqual({
|
|
47
|
+
kind: "iframe",
|
|
48
|
+
src: "https://www.youtube.com/embed/dQw4w9WgXcQ",
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it("Bilibili 视频页转换为官方播放器(BV 号 + 分 P)", () => {
|
|
53
|
+
expect(
|
|
54
|
+
resolveVideoEmbed("https://www.bilibili.com/video/BV1GJ411x7h7/"),
|
|
55
|
+
).toEqual({
|
|
56
|
+
kind: "iframe",
|
|
57
|
+
src: "https://player.bilibili.com/player.html?bvid=BV1GJ411x7h7&autoplay=0",
|
|
58
|
+
});
|
|
59
|
+
expect(
|
|
60
|
+
resolveVideoEmbed("https://www.bilibili.com/video/BV1GJ411x7h7?p=3"),
|
|
61
|
+
).toEqual({
|
|
62
|
+
kind: "iframe",
|
|
63
|
+
src: "https://player.bilibili.com/player.html?bvid=BV1GJ411x7h7&autoplay=0&p=3",
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it("Vimeo 转换为播放器", () => {
|
|
68
|
+
expect(resolveVideoEmbed("https://vimeo.com/76979871")).toEqual({
|
|
69
|
+
kind: "iframe",
|
|
70
|
+
src: "https://player.vimeo.com/video/76979871",
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it("b23.tv 短链无法本地解析,返回 null 交给原有探测逻辑", () => {
|
|
75
|
+
expect(resolveVideoEmbed("https://b23.tv/BV1GJ411x7h7")).toBeNull();
|
|
76
|
+
});
|
|
77
|
+
});
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// 视频链接识别与官方 embed 转换:供关联面板链接预览使用
|
|
2
|
+
// 返回 null 表示非视频链接(交由原有的可嵌入探测逻辑处理)
|
|
3
|
+
|
|
4
|
+
export type VideoEmbed =
|
|
5
|
+
| { kind: "file"; src: string }
|
|
6
|
+
| { kind: "iframe"; src: string };
|
|
7
|
+
|
|
8
|
+
const VIDEO_FILE_RE = /\.(mp4|webm|ogg|ogv|mov|m4v)$/i;
|
|
9
|
+
|
|
10
|
+
const YOUTUBE_ID_RE =
|
|
11
|
+
/^(?:https?:\/\/)?(?:www\.)?(?:youtube\.com\/(?:watch\?(?:.*&)?v=|shorts\/|embed\/)|youtu\.be\/)([A-Za-z0-9_-]{6,})/i;
|
|
12
|
+
|
|
13
|
+
const BILIBILI_BV_RE =
|
|
14
|
+
/^(?:https?:\/\/)?(?:www\.)?bilibili\.com\/video\/(BV[0-9A-Za-z]+)\/?(?:\?.*)?$/i;
|
|
15
|
+
|
|
16
|
+
const VIMEO_ID_RE = /^(?:https?:\/\/)?(?:www\.)?vimeo\.com\/(\d+)(?:\?.*)?$/i;
|
|
17
|
+
|
|
18
|
+
/** 解析 B 站分 P 参数(仅接受纯数字,防止参数注入) */
|
|
19
|
+
function getBilibiliPart(rawUrl: string): string | null {
|
|
20
|
+
try {
|
|
21
|
+
const p = new URL(rawUrl).searchParams.get("p");
|
|
22
|
+
return p && /^\d+$/.test(p) ? p : null;
|
|
23
|
+
} catch {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function resolveVideoEmbed(rawUrl: string): VideoEmbed | null {
|
|
29
|
+
if (!rawUrl) return null;
|
|
30
|
+
|
|
31
|
+
// 直链视频文件:扩展名只看 URL 路径末段,避免 query 中的伪扩展名误判
|
|
32
|
+
try {
|
|
33
|
+
const parsed = new URL(rawUrl);
|
|
34
|
+
if (VIDEO_FILE_RE.test(parsed.pathname)) {
|
|
35
|
+
return { kind: "file", src: rawUrl };
|
|
36
|
+
}
|
|
37
|
+
} catch {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const youtube = rawUrl.match(YOUTUBE_ID_RE);
|
|
42
|
+
if (youtube) {
|
|
43
|
+
return { kind: "iframe", src: `https://www.youtube.com/embed/${youtube[1]}` };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const bilibili = rawUrl.match(BILIBILI_BV_RE);
|
|
47
|
+
if (bilibili) {
|
|
48
|
+
const part = getBilibiliPart(rawUrl);
|
|
49
|
+
const src = `https://player.bilibili.com/player.html?bvid=${bilibili[1]}&autoplay=0${part ? `&p=${part}` : ""}`;
|
|
50
|
+
return { kind: "iframe", src };
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const vimeo = rawUrl.match(VIMEO_ID_RE);
|
|
54
|
+
if (vimeo) {
|
|
55
|
+
return { kind: "iframe", src: `https://player.vimeo.com/video/${vimeo[1]}` };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return null;
|
|
59
|
+
}
|
package/src/routeTree.gen.ts
CHANGED
|
@@ -31,6 +31,7 @@ import { Route as NavDashboardRouteRouteImport } from './routes/_nav/dashboard/r
|
|
|
31
31
|
import { Route as NavDesignRouteRouteImport } from './routes/_nav/design/route'
|
|
32
32
|
import { Route as NavInspirationRouteRouteImport } from './routes/_nav/inspiration/route'
|
|
33
33
|
import { Route as NavKnowledgeRouteRouteImport } from './routes/_nav/knowledge/route'
|
|
34
|
+
import { Route as NavNotificationsRouteRouteImport } from './routes/_nav/notifications/route'
|
|
34
35
|
import { Route as NavNotionLikeRouteRouteImport } from './routes/_nav/notion-like/route'
|
|
35
36
|
import { Route as NavPrdRouteRouteImport } from './routes/_nav/prd/route'
|
|
36
37
|
import { Route as NavPricing02RouteRouteImport } from './routes/_nav/pricing-02/route'
|
|
@@ -81,6 +82,7 @@ import { Route as NavTagsIdRouteRouteImport } from './routes/_nav/tags/$id/route
|
|
|
81
82
|
import { Route as NavTagsSettingsRouteRouteImport } from './routes/_nav/tags/settings/route'
|
|
82
83
|
import { Route as NavWorkspacesIndexRouteImport } from './routes/_nav/workspaces/index'
|
|
83
84
|
import { Route as NavWorkspacesWorkspaceIdRouteRouteImport } from './routes/_nav/workspaces/$workspaceId/route'
|
|
85
|
+
import { Route as ApiAttachmentsUploadRouteImport } from './routes/api/attachments/upload'
|
|
84
86
|
import { Route as ApiAuthSplatRouteImport } from './routes/api.auth.$'
|
|
85
87
|
import { Route as ApiAuthDesktopCallbackRouteImport } from './routes/api/auth/desktop-callback'
|
|
86
88
|
import { Route as ApiDesignUploadRouteImport } from './routes/api/design/upload'
|
|
@@ -99,6 +101,7 @@ import { Route as NavProjectsProjectIdStoryIdRouteRouteImport } from './routes/_
|
|
|
99
101
|
import { Route as NavProjectsProjectIdSettingsRouteRouteImport } from './routes/_nav/projects/$projectId/settings/route'
|
|
100
102
|
import { Route as NavSettingsAiProviderIdRouteRouteImport } from './routes/_nav/settings/ai/$providerId/route'
|
|
101
103
|
import { Route as NavWorkspacesWorkspaceIdSettingsRouteRouteImport } from './routes/_nav/workspaces/$workspaceId/settings/route'
|
|
104
|
+
import { Route as ApiAttachmentsIdContentRouteImport } from './routes/api/attachments/$id/content'
|
|
102
105
|
import { Route as DesignFilesProjectIdArtboardIdFilenameRouteImport } from './routes/design-files/$projectId/$artboardId/$filename'
|
|
103
106
|
import { Route as NavKnowledgeKbIdDocDocIdRouteRouteImport } from './routes/_nav/knowledge/$kbId/doc/$docId/route'
|
|
104
107
|
import { Route as ApiSharePrdPrdIdEventsRouteImport } from './routes/api/share/prd/$prdId/events'
|
|
@@ -259,6 +262,13 @@ const NavKnowledgeRouteRoute = NavKnowledgeRouteRouteImport.update({
|
|
|
259
262
|
path: '/knowledge',
|
|
260
263
|
getParentRoute: () => NavRouteRoute,
|
|
261
264
|
} as any)
|
|
265
|
+
const NavNotificationsRouteRoute = NavNotificationsRouteRouteImport.update({
|
|
266
|
+
id: '/notifications',
|
|
267
|
+
path: '/notifications',
|
|
268
|
+
getParentRoute: () => NavRouteRoute,
|
|
269
|
+
} as any).lazy(() =>
|
|
270
|
+
import('./routes/_nav/notifications/route.lazy').then((d) => d.Route),
|
|
271
|
+
)
|
|
262
272
|
const NavNotionLikeRouteRoute = NavNotionLikeRouteRouteImport.update({
|
|
263
273
|
id: '/notion-like',
|
|
264
274
|
path: '/notion-like',
|
|
@@ -567,6 +577,11 @@ const NavWorkspacesWorkspaceIdRouteRoute =
|
|
|
567
577
|
(d) => d.Route,
|
|
568
578
|
),
|
|
569
579
|
)
|
|
580
|
+
const ApiAttachmentsUploadRoute = ApiAttachmentsUploadRouteImport.update({
|
|
581
|
+
id: '/api/attachments/upload',
|
|
582
|
+
path: '/api/attachments/upload',
|
|
583
|
+
getParentRoute: () => rootRouteImport,
|
|
584
|
+
} as any)
|
|
570
585
|
const ApiAuthSplatRoute = ApiAuthSplatRouteImport.update({
|
|
571
586
|
id: '/api/auth/$',
|
|
572
587
|
path: '/api/auth/$',
|
|
@@ -782,6 +797,11 @@ const NavWorkspacesWorkspaceIdSettingsRouteRoute =
|
|
|
782
797
|
(d) => d.Route,
|
|
783
798
|
),
|
|
784
799
|
)
|
|
800
|
+
const ApiAttachmentsIdContentRoute = ApiAttachmentsIdContentRouteImport.update({
|
|
801
|
+
id: '/api/attachments/$id/content',
|
|
802
|
+
path: '/api/attachments/$id/content',
|
|
803
|
+
getParentRoute: () => rootRouteImport,
|
|
804
|
+
} as any)
|
|
785
805
|
const DesignFilesProjectIdArtboardIdFilenameRoute =
|
|
786
806
|
DesignFilesProjectIdArtboardIdFilenameRouteImport.update({
|
|
787
807
|
id: '/design-files/$projectId/$artboardId/$filename',
|
|
@@ -841,6 +861,7 @@ export interface FileRoutesByFullPath {
|
|
|
841
861
|
'/design': typeof NavDesignRouteRouteWithChildren
|
|
842
862
|
'/inspiration': typeof NavInspirationRouteRoute
|
|
843
863
|
'/knowledge': typeof NavKnowledgeRouteRouteWithChildren
|
|
864
|
+
'/notifications': typeof NavNotificationsRouteRoute
|
|
844
865
|
'/notion-like': typeof NavNotionLikeRouteRoute
|
|
845
866
|
'/prd': typeof NavPrdRouteRouteWithChildren
|
|
846
867
|
'/pricing-02': typeof NavPricing02RouteRoute
|
|
@@ -889,6 +910,7 @@ export interface FileRoutesByFullPath {
|
|
|
889
910
|
'/share/law/$id': typeof ShareLawIdRouteRoute
|
|
890
911
|
'/share/prd/$prdId': typeof SharePrdPrdIdRouteRoute
|
|
891
912
|
'/chat/$threadId': typeof NavChatThreadIdRoute
|
|
913
|
+
'/api/attachments/upload': typeof ApiAttachmentsUploadRoute
|
|
892
914
|
'/api/auth/$': typeof ApiAuthSplatRoute
|
|
893
915
|
'/api/auth/desktop-callback': typeof ApiAuthDesktopCallbackRoute
|
|
894
916
|
'/api/design/upload': typeof ApiDesignUploadRoute
|
|
@@ -907,6 +929,7 @@ export interface FileRoutesByFullPath {
|
|
|
907
929
|
'/projects/$projectId/settings': typeof NavProjectsProjectIdSettingsRouteRoute
|
|
908
930
|
'/settings/ai/$providerId': typeof NavSettingsAiProviderIdRouteRoute
|
|
909
931
|
'/workspaces/$workspaceId/settings': typeof NavWorkspacesWorkspaceIdSettingsRouteRoute
|
|
932
|
+
'/api/attachments/$id/content': typeof ApiAttachmentsIdContentRoute
|
|
910
933
|
'/design-files/$projectId/$artboardId/$filename': typeof DesignFilesProjectIdArtboardIdFilenameRoute
|
|
911
934
|
'/settings/ai/': typeof NavSettingsAiIndexRouteLazyRoute
|
|
912
935
|
'/knowledge/bookmarks/$id': typeof NavKnowledgeBookmarksIdLazyRoute
|
|
@@ -942,6 +965,7 @@ export interface FileRoutesByTo {
|
|
|
942
965
|
'/chat': typeof NavChatRouteRouteWithChildren
|
|
943
966
|
'/dashboard': typeof NavDashboardRouteRoute
|
|
944
967
|
'/inspiration': typeof NavInspirationRouteRoute
|
|
968
|
+
'/notifications': typeof NavNotificationsRouteRoute
|
|
945
969
|
'/notion-like': typeof NavNotionLikeRouteRoute
|
|
946
970
|
'/pricing-02': typeof NavPricing02RouteRoute
|
|
947
971
|
'/projects': typeof NavProjectsRouteRouteWithChildren
|
|
@@ -978,6 +1002,7 @@ export interface FileRoutesByTo {
|
|
|
978
1002
|
'/share/law/$id': typeof ShareLawIdRouteRoute
|
|
979
1003
|
'/share/prd/$prdId': typeof SharePrdPrdIdRouteRoute
|
|
980
1004
|
'/chat/$threadId': typeof NavChatThreadIdRoute
|
|
1005
|
+
'/api/attachments/upload': typeof ApiAttachmentsUploadRoute
|
|
981
1006
|
'/api/auth/$': typeof ApiAuthSplatRoute
|
|
982
1007
|
'/api/auth/desktop-callback': typeof ApiAuthDesktopCallbackRoute
|
|
983
1008
|
'/api/design/upload': typeof ApiDesignUploadRoute
|
|
@@ -996,6 +1021,7 @@ export interface FileRoutesByTo {
|
|
|
996
1021
|
'/projects/$projectId/settings': typeof NavProjectsProjectIdSettingsRouteRoute
|
|
997
1022
|
'/settings/ai/$providerId': typeof NavSettingsAiProviderIdRouteRoute
|
|
998
1023
|
'/workspaces/$workspaceId/settings': typeof NavWorkspacesWorkspaceIdSettingsRouteRoute
|
|
1024
|
+
'/api/attachments/$id/content': typeof ApiAttachmentsIdContentRoute
|
|
999
1025
|
'/design-files/$projectId/$artboardId/$filename': typeof DesignFilesProjectIdArtboardIdFilenameRoute
|
|
1000
1026
|
'/settings/ai': typeof NavSettingsAiIndexRouteLazyRoute
|
|
1001
1027
|
'/knowledge/bookmarks/$id': typeof NavKnowledgeBookmarksIdLazyRoute
|
|
@@ -1037,6 +1063,7 @@ export interface FileRoutesById {
|
|
|
1037
1063
|
'/_nav/design': typeof NavDesignRouteRouteWithChildren
|
|
1038
1064
|
'/_nav/inspiration': typeof NavInspirationRouteRoute
|
|
1039
1065
|
'/_nav/knowledge': typeof NavKnowledgeRouteRouteWithChildren
|
|
1066
|
+
'/_nav/notifications': typeof NavNotificationsRouteRoute
|
|
1040
1067
|
'/_nav/notion-like': typeof NavNotionLikeRouteRoute
|
|
1041
1068
|
'/_nav/prd': typeof NavPrdRouteRouteWithChildren
|
|
1042
1069
|
'/_nav/pricing-02': typeof NavPricing02RouteRoute
|
|
@@ -1085,6 +1112,7 @@ export interface FileRoutesById {
|
|
|
1085
1112
|
'/share/law/$id': typeof ShareLawIdRouteRoute
|
|
1086
1113
|
'/share/prd/$prdId': typeof SharePrdPrdIdRouteRoute
|
|
1087
1114
|
'/_nav/chat/$threadId': typeof NavChatThreadIdRoute
|
|
1115
|
+
'/api/attachments/upload': typeof ApiAttachmentsUploadRoute
|
|
1088
1116
|
'/api/auth/$': typeof ApiAuthSplatRoute
|
|
1089
1117
|
'/api/auth/desktop-callback': typeof ApiAuthDesktopCallbackRoute
|
|
1090
1118
|
'/api/design/upload': typeof ApiDesignUploadRoute
|
|
@@ -1103,6 +1131,7 @@ export interface FileRoutesById {
|
|
|
1103
1131
|
'/_nav/projects/$projectId/settings': typeof NavProjectsProjectIdSettingsRouteRoute
|
|
1104
1132
|
'/_nav/settings/ai/$providerId': typeof NavSettingsAiProviderIdRouteRoute
|
|
1105
1133
|
'/_nav/workspaces/$workspaceId/settings': typeof NavWorkspacesWorkspaceIdSettingsRouteRoute
|
|
1134
|
+
'/api/attachments/$id/content': typeof ApiAttachmentsIdContentRoute
|
|
1106
1135
|
'/design-files/$projectId/$artboardId/$filename': typeof DesignFilesProjectIdArtboardIdFilenameRoute
|
|
1107
1136
|
'/_nav/settings/ai/': typeof NavSettingsAiIndexRouteLazyRoute
|
|
1108
1137
|
'/_nav/knowledge/bookmarks/$id': typeof NavKnowledgeBookmarksIdLazyRoute
|
|
@@ -1142,6 +1171,7 @@ export interface FileRouteTypes {
|
|
|
1142
1171
|
| '/design'
|
|
1143
1172
|
| '/inspiration'
|
|
1144
1173
|
| '/knowledge'
|
|
1174
|
+
| '/notifications'
|
|
1145
1175
|
| '/notion-like'
|
|
1146
1176
|
| '/prd'
|
|
1147
1177
|
| '/pricing-02'
|
|
@@ -1190,6 +1220,7 @@ export interface FileRouteTypes {
|
|
|
1190
1220
|
| '/share/law/$id'
|
|
1191
1221
|
| '/share/prd/$prdId'
|
|
1192
1222
|
| '/chat/$threadId'
|
|
1223
|
+
| '/api/attachments/upload'
|
|
1193
1224
|
| '/api/auth/$'
|
|
1194
1225
|
| '/api/auth/desktop-callback'
|
|
1195
1226
|
| '/api/design/upload'
|
|
@@ -1208,6 +1239,7 @@ export interface FileRouteTypes {
|
|
|
1208
1239
|
| '/projects/$projectId/settings'
|
|
1209
1240
|
| '/settings/ai/$providerId'
|
|
1210
1241
|
| '/workspaces/$workspaceId/settings'
|
|
1242
|
+
| '/api/attachments/$id/content'
|
|
1211
1243
|
| '/design-files/$projectId/$artboardId/$filename'
|
|
1212
1244
|
| '/settings/ai/'
|
|
1213
1245
|
| '/knowledge/bookmarks/$id'
|
|
@@ -1243,6 +1275,7 @@ export interface FileRouteTypes {
|
|
|
1243
1275
|
| '/chat'
|
|
1244
1276
|
| '/dashboard'
|
|
1245
1277
|
| '/inspiration'
|
|
1278
|
+
| '/notifications'
|
|
1246
1279
|
| '/notion-like'
|
|
1247
1280
|
| '/pricing-02'
|
|
1248
1281
|
| '/projects'
|
|
@@ -1279,6 +1312,7 @@ export interface FileRouteTypes {
|
|
|
1279
1312
|
| '/share/law/$id'
|
|
1280
1313
|
| '/share/prd/$prdId'
|
|
1281
1314
|
| '/chat/$threadId'
|
|
1315
|
+
| '/api/attachments/upload'
|
|
1282
1316
|
| '/api/auth/$'
|
|
1283
1317
|
| '/api/auth/desktop-callback'
|
|
1284
1318
|
| '/api/design/upload'
|
|
@@ -1297,6 +1331,7 @@ export interface FileRouteTypes {
|
|
|
1297
1331
|
| '/projects/$projectId/settings'
|
|
1298
1332
|
| '/settings/ai/$providerId'
|
|
1299
1333
|
| '/workspaces/$workspaceId/settings'
|
|
1334
|
+
| '/api/attachments/$id/content'
|
|
1300
1335
|
| '/design-files/$projectId/$artboardId/$filename'
|
|
1301
1336
|
| '/settings/ai'
|
|
1302
1337
|
| '/knowledge/bookmarks/$id'
|
|
@@ -1337,6 +1372,7 @@ export interface FileRouteTypes {
|
|
|
1337
1372
|
| '/_nav/design'
|
|
1338
1373
|
| '/_nav/inspiration'
|
|
1339
1374
|
| '/_nav/knowledge'
|
|
1375
|
+
| '/_nav/notifications'
|
|
1340
1376
|
| '/_nav/notion-like'
|
|
1341
1377
|
| '/_nav/prd'
|
|
1342
1378
|
| '/_nav/pricing-02'
|
|
@@ -1385,6 +1421,7 @@ export interface FileRouteTypes {
|
|
|
1385
1421
|
| '/share/law/$id'
|
|
1386
1422
|
| '/share/prd/$prdId'
|
|
1387
1423
|
| '/_nav/chat/$threadId'
|
|
1424
|
+
| '/api/attachments/upload'
|
|
1388
1425
|
| '/api/auth/$'
|
|
1389
1426
|
| '/api/auth/desktop-callback'
|
|
1390
1427
|
| '/api/design/upload'
|
|
@@ -1403,6 +1440,7 @@ export interface FileRouteTypes {
|
|
|
1403
1440
|
| '/_nav/projects/$projectId/settings'
|
|
1404
1441
|
| '/_nav/settings/ai/$providerId'
|
|
1405
1442
|
| '/_nav/workspaces/$workspaceId/settings'
|
|
1443
|
+
| '/api/attachments/$id/content'
|
|
1406
1444
|
| '/design-files/$projectId/$artboardId/$filename'
|
|
1407
1445
|
| '/_nav/settings/ai/'
|
|
1408
1446
|
| '/_nav/knowledge/bookmarks/$id'
|
|
@@ -1438,12 +1476,14 @@ export interface RootRouteChildren {
|
|
|
1438
1476
|
ServerWsRoute: typeof ServerWsRoute
|
|
1439
1477
|
ApiLicenseActivateRouteRoute: typeof ApiLicenseActivateRouteRoute
|
|
1440
1478
|
ApiLicenseHeartbeatRouteRoute: typeof ApiLicenseHeartbeatRouteRoute
|
|
1479
|
+
ApiAttachmentsUploadRoute: typeof ApiAttachmentsUploadRoute
|
|
1441
1480
|
ApiAuthSplatRoute: typeof ApiAuthSplatRoute
|
|
1442
1481
|
ApiAuthDesktopCallbackRoute: typeof ApiAuthDesktopCallbackRoute
|
|
1443
1482
|
ApiDesignUploadRoute: typeof ApiDesignUploadRoute
|
|
1444
1483
|
ApiKnowledgeSyncGithubRoute: typeof ApiKnowledgeSyncGithubRoute
|
|
1445
1484
|
ApiNotificationsStreamRoute: typeof ApiNotificationsStreamRoute
|
|
1446
1485
|
ServerAnyhubProxySplatRoute: typeof ServerAnyhubProxySplatRoute
|
|
1486
|
+
ApiAttachmentsIdContentRoute: typeof ApiAttachmentsIdContentRoute
|
|
1447
1487
|
DesignFilesProjectIdArtboardIdFilenameRoute: typeof DesignFilesProjectIdArtboardIdFilenameRoute
|
|
1448
1488
|
ApiSharePrdPrdIdEventsRoute: typeof ApiSharePrdPrdIdEventsRoute
|
|
1449
1489
|
}
|
|
@@ -1590,6 +1630,13 @@ declare module '@tanstack/react-router' {
|
|
|
1590
1630
|
preLoaderRoute: typeof NavKnowledgeRouteRouteImport
|
|
1591
1631
|
parentRoute: typeof NavRouteRoute
|
|
1592
1632
|
}
|
|
1633
|
+
'/_nav/notifications': {
|
|
1634
|
+
id: '/_nav/notifications'
|
|
1635
|
+
path: '/notifications'
|
|
1636
|
+
fullPath: '/notifications'
|
|
1637
|
+
preLoaderRoute: typeof NavNotificationsRouteRouteImport
|
|
1638
|
+
parentRoute: typeof NavRouteRoute
|
|
1639
|
+
}
|
|
1593
1640
|
'/_nav/notion-like': {
|
|
1594
1641
|
id: '/_nav/notion-like'
|
|
1595
1642
|
path: '/notion-like'
|
|
@@ -1940,6 +1987,13 @@ declare module '@tanstack/react-router' {
|
|
|
1940
1987
|
preLoaderRoute: typeof NavWorkspacesWorkspaceIdRouteRouteImport
|
|
1941
1988
|
parentRoute: typeof NavWorkspacesRouteRoute
|
|
1942
1989
|
}
|
|
1990
|
+
'/api/attachments/upload': {
|
|
1991
|
+
id: '/api/attachments/upload'
|
|
1992
|
+
path: '/api/attachments/upload'
|
|
1993
|
+
fullPath: '/api/attachments/upload'
|
|
1994
|
+
preLoaderRoute: typeof ApiAttachmentsUploadRouteImport
|
|
1995
|
+
parentRoute: typeof rootRouteImport
|
|
1996
|
+
}
|
|
1943
1997
|
'/api/auth/$': {
|
|
1944
1998
|
id: '/api/auth/$'
|
|
1945
1999
|
path: '/api/auth/$'
|
|
@@ -2143,6 +2197,13 @@ declare module '@tanstack/react-router' {
|
|
|
2143
2197
|
preLoaderRoute: typeof NavWorkspacesWorkspaceIdSettingsRouteRouteImport
|
|
2144
2198
|
parentRoute: typeof NavWorkspacesWorkspaceIdRouteRoute
|
|
2145
2199
|
}
|
|
2200
|
+
'/api/attachments/$id/content': {
|
|
2201
|
+
id: '/api/attachments/$id/content'
|
|
2202
|
+
path: '/api/attachments/$id/content'
|
|
2203
|
+
fullPath: '/api/attachments/$id/content'
|
|
2204
|
+
preLoaderRoute: typeof ApiAttachmentsIdContentRouteImport
|
|
2205
|
+
parentRoute: typeof rootRouteImport
|
|
2206
|
+
}
|
|
2146
2207
|
'/design-files/$projectId/$artboardId/$filename': {
|
|
2147
2208
|
id: '/design-files/$projectId/$artboardId/$filename'
|
|
2148
2209
|
path: '/design-files/$projectId/$artboardId/$filename'
|
|
@@ -2543,6 +2604,7 @@ interface NavRouteRouteChildren {
|
|
|
2543
2604
|
NavDesignRouteRoute: typeof NavDesignRouteRouteWithChildren
|
|
2544
2605
|
NavInspirationRouteRoute: typeof NavInspirationRouteRoute
|
|
2545
2606
|
NavKnowledgeRouteRoute: typeof NavKnowledgeRouteRouteWithChildren
|
|
2607
|
+
NavNotificationsRouteRoute: typeof NavNotificationsRouteRoute
|
|
2546
2608
|
NavNotionLikeRouteRoute: typeof NavNotionLikeRouteRoute
|
|
2547
2609
|
NavPrdRouteRoute: typeof NavPrdRouteRouteWithChildren
|
|
2548
2610
|
NavPricing02RouteRoute: typeof NavPricing02RouteRoute
|
|
@@ -2565,6 +2627,7 @@ const NavRouteRouteChildren: NavRouteRouteChildren = {
|
|
|
2565
2627
|
NavDesignRouteRoute: NavDesignRouteRouteWithChildren,
|
|
2566
2628
|
NavInspirationRouteRoute: NavInspirationRouteRoute,
|
|
2567
2629
|
NavKnowledgeRouteRoute: NavKnowledgeRouteRouteWithChildren,
|
|
2630
|
+
NavNotificationsRouteRoute: NavNotificationsRouteRoute,
|
|
2568
2631
|
NavNotionLikeRouteRoute: NavNotionLikeRouteRoute,
|
|
2569
2632
|
NavPrdRouteRoute: NavPrdRouteRouteWithChildren,
|
|
2570
2633
|
NavPricing02RouteRoute: NavPricing02RouteRoute,
|
|
@@ -2628,12 +2691,14 @@ const rootRouteChildren: RootRouteChildren = {
|
|
|
2628
2691
|
ServerWsRoute: ServerWsRoute,
|
|
2629
2692
|
ApiLicenseActivateRouteRoute: ApiLicenseActivateRouteRoute,
|
|
2630
2693
|
ApiLicenseHeartbeatRouteRoute: ApiLicenseHeartbeatRouteRoute,
|
|
2694
|
+
ApiAttachmentsUploadRoute: ApiAttachmentsUploadRoute,
|
|
2631
2695
|
ApiAuthSplatRoute: ApiAuthSplatRoute,
|
|
2632
2696
|
ApiAuthDesktopCallbackRoute: ApiAuthDesktopCallbackRoute,
|
|
2633
2697
|
ApiDesignUploadRoute: ApiDesignUploadRoute,
|
|
2634
2698
|
ApiKnowledgeSyncGithubRoute: ApiKnowledgeSyncGithubRoute,
|
|
2635
2699
|
ApiNotificationsStreamRoute: ApiNotificationsStreamRoute,
|
|
2636
2700
|
ServerAnyhubProxySplatRoute: ServerAnyhubProxySplatRoute,
|
|
2701
|
+
ApiAttachmentsIdContentRoute: ApiAttachmentsIdContentRoute,
|
|
2637
2702
|
DesignFilesProjectIdArtboardIdFilenameRoute:
|
|
2638
2703
|
DesignFilesProjectIdArtboardIdFilenameRoute,
|
|
2639
2704
|
ApiSharePrdPrdIdEventsRoute: ApiSharePrdPrdIdEventsRoute,
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
+
|
|
3
|
+
import { createLazyFileRoute } from '@tanstack/react-router'
|
|
4
|
+
import { useTranslation } from 'react-i18next'
|
|
5
|
+
import { TeamNotificationsPanel } from '@/components/notifications/team-notifications'
|
|
6
|
+
|
|
7
|
+
export const Route = createLazyFileRoute('/_nav/notifications')({
|
|
8
|
+
component: NotificationsPage,
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
function NotificationsPage() {
|
|
12
|
+
const { t } = useTranslation('notifications')
|
|
13
|
+
return (
|
|
14
|
+
<div className="flex h-full flex-col gap-6 overflow-hidden p-6">
|
|
15
|
+
<div className="flex shrink-0 flex-col gap-1">
|
|
16
|
+
<h1 className="text-xl font-semibold">{t('title')}</h1>
|
|
17
|
+
<p className="text-sm text-muted-foreground">{t('description')}</p>
|
|
18
|
+
</div>
|
|
19
|
+
<TeamNotificationsPanel />
|
|
20
|
+
</div>
|
|
21
|
+
)
|
|
22
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
+
|
|
3
|
+
import { createFileRoute } from '@tanstack/react-router'
|
|
4
|
+
import type { NotificationListResult } from '@allbluecn/shared'
|
|
5
|
+
import { NOTIFICATION_LIST_KEY, NOTIFICATION_UNREAD_KEY } from '@/hooks/use-notifications'
|
|
6
|
+
import { getUnreadCountFn, listNotificationsFn } from '@/server/serverFns/notifications'
|
|
7
|
+
|
|
8
|
+
export const Route = createFileRoute('/_nav/notifications')({
|
|
9
|
+
loader: async ({ context }) => {
|
|
10
|
+
const { queryClient } = context
|
|
11
|
+
// SSR 预取未读数 + 列表第一页,保证服务端与客户端 hydrate 首帧渲染一致
|
|
12
|
+
// (否则 SSR 渲染空态、客户端首帧已有数据 → hydration mismatch 整树重渲染)
|
|
13
|
+
await Promise.all([
|
|
14
|
+
queryClient.ensureQueryData({
|
|
15
|
+
queryKey: NOTIFICATION_UNREAD_KEY,
|
|
16
|
+
queryFn: () => getUnreadCountFn({ data: {} }),
|
|
17
|
+
}),
|
|
18
|
+
queryClient.fetchInfiniteQuery({
|
|
19
|
+
queryKey: [...NOTIFICATION_LIST_KEY, undefined],
|
|
20
|
+
queryFn: ({ pageParam }) =>
|
|
21
|
+
listNotificationsFn({ data: pageParam ? { cursor: pageParam } : {} }),
|
|
22
|
+
initialPageParam: undefined as string | undefined,
|
|
23
|
+
getNextPageParam: (lastPage: NotificationListResult) =>
|
|
24
|
+
lastPage.hasMore ? lastPage.items[lastPage.items.length - 1].id : undefined,
|
|
25
|
+
}),
|
|
26
|
+
]).catch(() => {
|
|
27
|
+
// 预取失败降级为客户端 fetch(与旧行为一致),不阻塞页面
|
|
28
|
+
})
|
|
29
|
+
},
|
|
30
|
+
})
|