Skip to content

Commit 9e4bee2

Browse files
Merge pull request #289 from boostcampwm-2024/feature-fe-#287
tanstack 라우터 추가, 워크 스페이스 및 소켓 룸 분리
2 parents d1228f2 + 5f343a3 commit 9e4bee2

File tree

14 files changed

+497
-61
lines changed

14 files changed

+497
-61
lines changed

apps/frontend/.prettierrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
2+
"ignore": ["**/routeTree.gen.ts", "dist"],
23
"printWidth": 80,
34
"tabWidth": 2,
45
"plugins": ["prettier-plugin-tailwindcss"]

apps/frontend/eslint.config.js

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
1-
import js from '@eslint/js'
2-
import globals from 'globals'
3-
import reactHooks from 'eslint-plugin-react-hooks'
4-
import reactRefresh from 'eslint-plugin-react-refresh'
5-
import tseslint from 'typescript-eslint'
1+
import js from "@eslint/js";
2+
import globals from "globals";
3+
import reactHooks from "eslint-plugin-react-hooks";
4+
import reactRefresh from "eslint-plugin-react-refresh";
5+
import tseslint from "typescript-eslint";
66

77
export default tseslint.config(
8-
{ ignores: ['dist'] },
8+
{ ignores: ["dist", "**/routeTree.gen.ts"] },
99
{
1010
extends: [js.configs.recommended, ...tseslint.configs.recommended],
11-
files: ['**/*.{ts,tsx}'],
11+
files: ["**/*.{ts,tsx}"],
1212
languageOptions: {
1313
ecmaVersion: 2020,
1414
globals: globals.browser,
1515
},
1616
plugins: {
17-
'react-hooks': reactHooks,
18-
'react-refresh': reactRefresh,
17+
"react-hooks": reactHooks,
18+
"react-refresh": reactRefresh,
1919
},
2020
rules: {
2121
...reactHooks.configs.recommended.rules,
22-
'react-refresh/only-export-components': [
23-
'warn',
22+
"react-refresh/only-export-components": [
23+
"warn",
2424
{ allowConstantExport: true },
2525
],
2626
},
2727
},
28-
)
28+
);

apps/frontend/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"@radix-ui/react-separator": "^1.1.0",
2424
"@radix-ui/react-slot": "^1.1.0",
2525
"@tanstack/react-query": "^5.59.19",
26+
"@tanstack/react-router": "^1.82.12",
2627
"@tiptap/extension-collaboration": "^2.9.1",
2728
"@tiptap/extension-collaboration-cursor": "^2.9.1",
2829
"@uiw/react-color": "^2.3.2",
@@ -56,6 +57,8 @@
5657
"devDependencies": {
5758
"@eslint/js": "^9.13.0",
5859
"@tailwindcss/typography": "^0.5.15",
60+
"@tanstack/router-devtools": "^1.82.12",
61+
"@tanstack/router-plugin": "^1.82.10",
5962
"@types/react": "^18.3.12",
6063
"@types/react-dom": "^18.3.1",
6164
"@vitejs/plugin-react": "^4.3.3",

apps/frontend/src/app/App.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,28 @@
1+
import { useEffect } from "react";
2+
import * as Y from "yjs";
3+
14
import { useSyncedUsers } from "@/entities/user/model";
25
import { SideWrapper } from "@/shared/ui";
36
import { CanvasView } from "@/widgets/CanvasView";
47
import { EditorView } from "@/widgets/EditorView";
58
import { PageSideBarView } from "@/widgets/PageSideBarView";
69
import { CanvasToolsView } from "@/widgets/CanvasToolsView";
10+
import { useWorkspace } from "@/shared/lib/useWorkspace";
11+
import useYDocStore from "@/shared/model/ydocStore";
712
import { useGetUser } from "@/features/auth/model/useAuth";
813

914
function App() {
1015
useSyncedUsers();
1116
useGetUser();
1217

18+
const workspace = useWorkspace();
19+
const { setYDoc } = useYDocStore();
20+
21+
useEffect(() => {
22+
const doc = new Y.Doc({ guid: workspace });
23+
setYDoc(doc);
24+
}, [workspace, setYDoc]);
25+
1326
return (
1427
<div className="fixed inset-0 bg-white">
1528
<SideWrapper side="right" className="z-50">

apps/frontend/src/app/main.tsx

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,23 @@
11
import { StrictMode } from "react";
22
import { createRoot } from "react-dom/client";
33
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
4-
4+
import { RouterProvider, createRouter } from "@tanstack/react-router";
55
import "../shared/index.css";
6-
import App from "./App.tsx";
6+
import { routeTree } from "@/routeTree.gen";
77

88
const queryClient = new QueryClient();
99

10+
const router = createRouter({ routeTree });
11+
declare module "@tanstack/react-router" {
12+
interface Register {
13+
router: typeof router;
14+
}
15+
}
16+
1017
createRoot(document.getElementById("root")!).render(
11-
<QueryClientProvider client={queryClient}>
12-
<StrictMode>
13-
<App />
14-
</StrictMode>
15-
</QueryClientProvider>,
18+
<StrictMode>
19+
<QueryClientProvider client={queryClient}>
20+
<RouterProvider router={router} />
21+
</QueryClientProvider>
22+
</StrictMode>,
1623
);

apps/frontend/src/features/canvas/model/useCanvas.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import { createSocketIOProvider } from "@/shared/api/socketProvider";
2121
import { useCollaborativeCursors } from "./useCollaborativeCursors";
2222
import { getSortedNodes } from "./sortNodes";
2323
import { usePageStore } from "@/features/pageSidebar/model/pageStore";
24+
import { useWorkspace } from "@/shared/lib/useWorkspace";
25+
2426
export interface YNode extends Node {
2527
isHolding: boolean;
2628
}
@@ -32,10 +34,12 @@ export const useCanvas = () => {
3234
const queryClient = useQueryClient();
3335
const { ydoc } = useYDocStore();
3436

37+
const workspace = useWorkspace();
38+
3539
const { cursors, handleMouseMove, handleNodeDrag, handleMouseLeave } =
3640
useCollaborativeCursors({
3741
ydoc,
38-
roomName: "flow-room",
42+
roomName: `flow-room-${workspace}`,
3943
});
4044

4145
const provider = useRef<SocketIOProvider>();

apps/frontend/src/features/canvas/model/useCollaborativeCursors.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import { useReactFlow, type XYPosition } from "@xyflow/react";
66
import { createSocketIOProvider } from "@/shared/api/socketProvider";
77
import { useUserStore } from "@/entities/user/model";
88

9+
import { useWorkspace } from "@/shared/lib/useWorkspace";
10+
911
export interface AwarenessState {
1012
cursor: XYPosition | null;
1113
color: string;
@@ -28,9 +30,10 @@ export function useCollaborativeCursors({
2830
);
2931
const { currentUser } = useUserStore();
3032
const { color, clientId } = currentUser;
33+
const workspace = useWorkspace();
3134

3235
useEffect(() => {
33-
const wsProvider = createSocketIOProvider("flow-room", ydoc);
36+
const wsProvider = createSocketIOProvider(`flow-room-${workspace}`, ydoc);
3437
provider.current = wsProvider;
3538

3639
wsProvider.awareness.setLocalState({

apps/frontend/src/routeTree.gen.ts

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/* eslint-disable */
2+
3+
// @ts-nocheck
4+
5+
// noinspection JSUnusedGlobalSymbols
6+
7+
// This file was automatically generated by TanStack Router.
8+
// You should NOT make any changes in this file as it will be overwritten.
9+
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
10+
11+
// Import Routes
12+
13+
import { Route as rootRoute } from './routes/__root'
14+
import { Route as IndexImport } from './routes/index'
15+
import { Route as WorkspaceWorkspaceIdImport } from './routes/workspace/$workspaceId'
16+
17+
// Create/Update Routes
18+
19+
const IndexRoute = IndexImport.update({
20+
id: '/',
21+
path: '/',
22+
getParentRoute: () => rootRoute,
23+
} as any)
24+
25+
const WorkspaceWorkspaceIdRoute = WorkspaceWorkspaceIdImport.update({
26+
id: '/workspace/$workspaceId',
27+
path: '/workspace/$workspaceId',
28+
getParentRoute: () => rootRoute,
29+
} as any)
30+
31+
// Populate the FileRoutesByPath interface
32+
33+
declare module '@tanstack/react-router' {
34+
interface FileRoutesByPath {
35+
'/': {
36+
id: '/'
37+
path: '/'
38+
fullPath: '/'
39+
preLoaderRoute: typeof IndexImport
40+
parentRoute: typeof rootRoute
41+
}
42+
'/workspace/$workspaceId': {
43+
id: '/workspace/$workspaceId'
44+
path: '/workspace/$workspaceId'
45+
fullPath: '/workspace/$workspaceId'
46+
preLoaderRoute: typeof WorkspaceWorkspaceIdImport
47+
parentRoute: typeof rootRoute
48+
}
49+
}
50+
}
51+
52+
// Create and export the route tree
53+
54+
export interface FileRoutesByFullPath {
55+
'/': typeof IndexRoute
56+
'/workspace/$workspaceId': typeof WorkspaceWorkspaceIdRoute
57+
}
58+
59+
export interface FileRoutesByTo {
60+
'/': typeof IndexRoute
61+
'/workspace/$workspaceId': typeof WorkspaceWorkspaceIdRoute
62+
}
63+
64+
export interface FileRoutesById {
65+
__root__: typeof rootRoute
66+
'/': typeof IndexRoute
67+
'/workspace/$workspaceId': typeof WorkspaceWorkspaceIdRoute
68+
}
69+
70+
export interface FileRouteTypes {
71+
fileRoutesByFullPath: FileRoutesByFullPath
72+
fullPaths: '/' | '/workspace/$workspaceId'
73+
fileRoutesByTo: FileRoutesByTo
74+
to: '/' | '/workspace/$workspaceId'
75+
id: '__root__' | '/' | '/workspace/$workspaceId'
76+
fileRoutesById: FileRoutesById
77+
}
78+
79+
export interface RootRouteChildren {
80+
IndexRoute: typeof IndexRoute
81+
WorkspaceWorkspaceIdRoute: typeof WorkspaceWorkspaceIdRoute
82+
}
83+
84+
const rootRouteChildren: RootRouteChildren = {
85+
IndexRoute: IndexRoute,
86+
WorkspaceWorkspaceIdRoute: WorkspaceWorkspaceIdRoute,
87+
}
88+
89+
export const routeTree = rootRoute
90+
._addFileChildren(rootRouteChildren)
91+
._addFileTypes<FileRouteTypes>()
92+
93+
/* ROUTE_MANIFEST_START
94+
{
95+
"routes": {
96+
"__root__": {
97+
"filePath": "__root.tsx",
98+
"children": [
99+
"/",
100+
"/workspace/$workspaceId"
101+
]
102+
},
103+
"/": {
104+
"filePath": "index.tsx"
105+
},
106+
"/workspace/$workspaceId": {
107+
"filePath": "workspace/$workspaceId.tsx"
108+
}
109+
}
110+
}
111+
ROUTE_MANIFEST_END */
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { createRootRoute, Outlet } from "@tanstack/react-router";
2+
3+
export const Route = createRootRoute({
4+
component: () => <Outlet />,
5+
});

apps/frontend/src/routes/index.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { createFileRoute } from "@tanstack/react-router";
2+
import App from "@/app/App";
3+
4+
export const Route = createFileRoute("/")({
5+
component: App,
6+
});

0 commit comments

Comments
 (0)