From f95628636506a64e11a6314abbff53b84d29103b Mon Sep 17 00:00:00 2001 From: Hogyun Jeon Date: Wed, 27 Nov 2024 19:24:44 +0900 Subject: [PATCH 1/9] =?UTF-8?q?feat:=20yjs=20connection=20=EC=97=B0?= =?UTF-8?q?=EA=B2=B0=20=EA=B1=B0=EB=B6=80=20=EC=8B=9C=20=EC=9E=AC=EC=97=B0?= =?UTF-8?q?=EA=B2=B0=20=EC=8B=9C=EB=8F=84=ED=95=98=EC=A7=80=20=EC=95=8A?= =?UTF-8?q?=EA=B3=A0,=20=EA=B4=80=EB=A0=A8=20=EC=A0=95=EB=B3=B4=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=EB=A1=9C=20=EC=A0=84=EB=8B=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/hooks/yjs/useYjsConnection.tsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/frontend/src/hooks/yjs/useYjsConnection.tsx b/packages/frontend/src/hooks/yjs/useYjsConnection.tsx index 23d19172..75651211 100644 --- a/packages/frontend/src/hooks/yjs/useYjsConnection.tsx +++ b/packages/frontend/src/hooks/yjs/useYjsConnection.tsx @@ -6,6 +6,7 @@ import * as Y from "yjs"; import { generateUserColor } from "@/lib/utils"; export default function useYjsConnection(docName: string) { + const [error, setError] = useState(); const [yDoc, setYDoc] = useState(); const [yProvider, setYProvider] = useState(); @@ -31,6 +32,13 @@ export default function useYjsConnection(docName: string) { }, ); + provider.on("connection-close", (event: CloseEvent) => { + if (event.code === 1008) { + provider.shouldConnect = false; + setError(new Error("찾을 수 없거나 접근할 수 없는 스페이스예요.")); + } + }); + return () => { if (provider.bcconnected || provider.wsconnected) { provider.disconnect(); @@ -41,5 +49,5 @@ export default function useYjsConnection(docName: string) { }; }, [docName]); - return { yProvider, yDoc, setYProvider, setYDoc }; + return { error, yProvider, yDoc, setYProvider, setYDoc }; } From f2033ff3d9949dd19adc4955a8a5f90c8d3cf614 Mon Sep 17 00:00:00 2001 From: Hogyun Jeon Date: Thu, 28 Nov 2024 15:34:02 +0900 Subject: [PATCH 2/9] =?UTF-8?q?feat:=20=EC=97=90=EB=9F=AC=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EC=84=B9=EC=85=98=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/assets/error-logo.svg | 30 +++++++++++++++++++ .../frontend/src/components/ErrorSection.tsx | 29 ++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 packages/frontend/src/assets/error-logo.svg create mode 100644 packages/frontend/src/components/ErrorSection.tsx diff --git a/packages/frontend/src/assets/error-logo.svg b/packages/frontend/src/assets/error-logo.svg new file mode 100644 index 00000000..5bc9c350 --- /dev/null +++ b/packages/frontend/src/assets/error-logo.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/frontend/src/components/ErrorSection.tsx b/packages/frontend/src/components/ErrorSection.tsx new file mode 100644 index 00000000..e5cf5956 --- /dev/null +++ b/packages/frontend/src/components/ErrorSection.tsx @@ -0,0 +1,29 @@ +import { ReactNode } from "react"; + +import buzzyLogo from "@/assets/error-logo.svg"; + +type ErrorSectionProps = { + description: string; + RestoreActions?: () => ReactNode; +}; + +export default function ErrorSection({ + description, + RestoreActions, +}: ErrorSectionProps) { + return ( +
+
+ +
+

{description}

+
+ {RestoreActions && ( +
+ +
+ )} +
+
+ ); +} From 2850a636ade05d4d4982590c5a9f217c77532a9a Mon Sep 17 00:00:00 2001 From: Hogyun Jeon Date: Thu, 28 Nov 2024 15:36:04 +0900 Subject: [PATCH 3/9] =?UTF-8?q?feat:=20yjs=20connection=20=EC=83=81?= =?UTF-8?q?=ED=83=9C=20=EC=B6=94=EC=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/hooks/yjs/useYjsConnection.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/frontend/src/hooks/yjs/useYjsConnection.tsx b/packages/frontend/src/hooks/yjs/useYjsConnection.tsx index 75651211..3f13fbc9 100644 --- a/packages/frontend/src/hooks/yjs/useYjsConnection.tsx +++ b/packages/frontend/src/hooks/yjs/useYjsConnection.tsx @@ -6,11 +6,16 @@ import * as Y from "yjs"; import { generateUserColor } from "@/lib/utils"; export default function useYjsConnection(docName: string) { + const [status, setStatus] = useState< + "connecting" | "connected" | "disconnected" + >("connecting"); const [error, setError] = useState(); const [yDoc, setYDoc] = useState(); const [yProvider, setYProvider] = useState(); useEffect(() => { + setStatus("connecting"); + const doc = new Y.Doc(); const provider = new WebsocketProvider( `ws://${import.meta.env.DEV ? "localhost" : "www.honeyflow.life"}/ws/space`, @@ -29,10 +34,11 @@ export default function useYjsConnection(docName: string) { if (event.status === "connected") { awareness.setLocalStateField("color", generateUserColor()); } + setStatus(event.status); }, ); - provider.on("connection-close", (event: CloseEvent) => { + provider.once("connection-close", (event: CloseEvent) => { if (event.code === 1008) { provider.shouldConnect = false; setError(new Error("찾을 수 없거나 접근할 수 없는 스페이스예요.")); @@ -49,5 +55,5 @@ export default function useYjsConnection(docName: string) { }; }, [docName]); - return { error, yProvider, yDoc, setYProvider, setYDoc }; + return { status, error, yProvider, yDoc, setYProvider, setYDoc }; } From 5600361c894184e10c5e7a5a09dfd8c3db7eac77 Mon Sep 17 00:00:00 2001 From: Hogyun Jeon Date: Thu, 28 Nov 2024 15:37:45 +0900 Subject: [PATCH 4/9] =?UTF-8?q?feat:=20=EC=8A=A4=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=8A=A4=20=EC=83=9D=EC=84=B1=20=EB=A1=9C=EB=94=A9=20=EC=83=81?= =?UTF-8?q?=ED=83=9C=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/pages/Home.tsx | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/packages/frontend/src/pages/Home.tsx b/packages/frontend/src/pages/Home.tsx index 1a9ad136..1f64b66e 100644 --- a/packages/frontend/src/pages/Home.tsx +++ b/packages/frontend/src/pages/Home.tsx @@ -31,7 +31,9 @@ type CreateSpaceButtonProps = { function CreateSpaceButton({ navigate }: CreateSpaceButtonProps) { const [spaceName, setSpaceName] = useState(""); + const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(""); + const handleCreateSpace = (e: FormEvent) => { e.preventDefault(); const targetSpaceName = spaceName.trim(); @@ -41,6 +43,8 @@ function CreateSpaceButton({ navigate }: CreateSpaceButtonProps) { return; } + setIsLoading(true); + requestCreateSpace(targetSpaceName) .then((res) => { const { urlPath } = res; @@ -48,6 +52,9 @@ function CreateSpaceButton({ navigate }: CreateSpaceButtonProps) { }) .catch((error) => { setError(`스페이스 생성에 실패했어요. (${error})`); + }) + .finally(() => { + setIsLoading(false); }); }; @@ -77,9 +84,21 @@ function CreateSpaceButton({ navigate }: CreateSpaceButtonProps) { {error &&

{error}

} - + - + From b399f337411a3ea53949a9e71181afd6d22b324e Mon Sep 17 00:00:00 2001 From: Hogyun Jeon Date: Thu, 28 Nov 2024 15:41:05 +0900 Subject: [PATCH 5/9] =?UTF-8?q?feat:=20space=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=EB=B0=8F=20=EB=A1=9C=EB=94=A9=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/pages/Space.tsx | 34 +++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/packages/frontend/src/pages/Space.tsx b/packages/frontend/src/pages/Space.tsx index 8873839f..f8efb4d2 100644 --- a/packages/frontend/src/pages/Space.tsx +++ b/packages/frontend/src/pages/Space.tsx @@ -1,8 +1,12 @@ import { useRef } from "react"; -import { useParams } from "react-router-dom"; +import { useNavigate, useParams } from "react-router-dom"; +import { MoveLeftIcon } from "lucide-react"; + +import ErrorSection from "@/components/ErrorSection"; import SpacePageHeader from "@/components/space/SpacePageHeader"; import SpaceView from "@/components/space/SpaceView"; +import { Button } from "@/components/ui/button"; import useYjsConnection from "@/hooks/yjs/useYjsConnection"; import { YjsStoreProvider } from "@/store/yjs"; @@ -11,15 +15,41 @@ interface SpacePageParams extends Record { } export default function SpacePage() { + const navigate = useNavigate(); const { spaceId } = useParams(); if (!spaceId) { throw new Error(""); } - const { yDoc, yProvider, setYDoc, setYProvider } = useYjsConnection(spaceId); + const { error, status, yDoc, yProvider, setYDoc, setYProvider } = + useYjsConnection(spaceId); const containerRef = useRef(null); + if (error) { + return ( + ( + <> + + + )} + /> + ); + } + + if (status === "connecting") { + return ( +
+
+
+ ); + } + return (
From 884e45319fdc153fcccf3a0cf4940710cd1e6d9a Mon Sep 17 00:00:00 2001 From: Hogyun Jeon Date: Thu, 28 Nov 2024 15:47:07 +0900 Subject: [PATCH 6/9] =?UTF-8?q?feat:=20not=20found=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/App.tsx | 2 ++ packages/frontend/src/pages/NotFound.tsx | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 packages/frontend/src/pages/NotFound.tsx diff --git a/packages/frontend/src/App.tsx b/packages/frontend/src/App.tsx index 7f41c5ed..cfacd7bd 100644 --- a/packages/frontend/src/App.tsx +++ b/packages/frontend/src/App.tsx @@ -3,6 +3,7 @@ import { BrowserRouter, Route, Routes } from "react-router-dom"; import "./App.css"; import Editor from "./components/note/Editor.tsx"; import Home from "./pages/Home.tsx"; +import NotFoundPage from "./pages/NotFound.tsx"; import SpacePage from "./pages/Space.tsx"; function App() { @@ -12,6 +13,7 @@ function App() { } /> } /> } /> + } /> ); diff --git a/packages/frontend/src/pages/NotFound.tsx b/packages/frontend/src/pages/NotFound.tsx new file mode 100644 index 00000000..a6d63fe6 --- /dev/null +++ b/packages/frontend/src/pages/NotFound.tsx @@ -0,0 +1,22 @@ +import { Link } from "react-router-dom"; + +import { MoveLeftIcon } from "lucide-react"; + +import ErrorSection from "@/components/ErrorSection"; +import { Button } from "@/components/ui/button"; + +export default function NotFoundPage() { + return ( + ( + + )} + /> + ); +} From e78cd83e7fc998cd4f177ca7f9c666baa391b8de Mon Sep 17 00:00:00 2001 From: Hogyun Jeon Date: Thu, 28 Nov 2024 18:24:57 +0900 Subject: [PATCH 7/9] =?UTF-8?q?fix:=20=ED=98=84=EC=9E=AC=20=EB=8F=99?= =?UTF-8?q?=EC=9E=91=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20=ED=8C=94?= =?UTF-8?q?=EB=A0=88=ED=8A=B8=20=EB=A9=94=EB=89=B4=20=EB=B2=84=ED=8A=BC=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/components/space/SpaceView.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/frontend/src/components/space/SpaceView.tsx b/packages/frontend/src/components/space/SpaceView.tsx index 91df39af..a0c23e77 100644 --- a/packages/frontend/src/components/space/SpaceView.tsx +++ b/packages/frontend/src/components/space/SpaceView.tsx @@ -296,7 +296,8 @@ export default function SpaceView({ spaceId, autofitTo }: SpaceViewProps) { }} >
From fcf1c6c59f911d9c02448caacd6ba73edb5a6276 Mon Sep 17 00:00:00 2001 From: Hogyun Jeon Date: Thu, 28 Nov 2024 18:25:31 +0900 Subject: [PATCH 8/9] =?UTF-8?q?feat:=20space=20=EB=A1=9C=EB=94=A9=20?= =?UTF-8?q?=EC=8A=A4=ED=83=80=EC=9D=BC=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/pages/Space.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/frontend/src/pages/Space.tsx b/packages/frontend/src/pages/Space.tsx index f8efb4d2..308edb2e 100644 --- a/packages/frontend/src/pages/Space.tsx +++ b/packages/frontend/src/pages/Space.tsx @@ -1,7 +1,7 @@ import { useRef } from "react"; import { useNavigate, useParams } from "react-router-dom"; -import { MoveLeftIcon } from "lucide-react"; +import { CircleDashedIcon, MoveLeftIcon } from "lucide-react"; import ErrorSection from "@/components/ErrorSection"; import SpacePageHeader from "@/components/space/SpacePageHeader"; @@ -45,7 +45,7 @@ export default function SpacePage() { if (status === "connecting") { return (
-
+
); } From 00131d1aad47d984f4fa1e4c9489f62f6c7b200c Mon Sep 17 00:00:00 2001 From: Hogyun Jeon Date: Thu, 28 Nov 2024 18:26:09 +0900 Subject: [PATCH 9/9] =?UTF-8?q?fix:=20=EC=9E=98=EB=AA=BB=EB=90=9C=20uid=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/lib/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend/src/lib/utils.ts b/packages/frontend/src/lib/utils.ts index 5f0d8703..bc348d84 100644 --- a/packages/frontend/src/lib/utils.ts +++ b/packages/frontend/src/lib/utils.ts @@ -88,7 +88,7 @@ export function createSafeContext(defaultValue?: T) { } export function generateUniqueId() { - return Math.random().toString(36); + return Math.random().toString(36).slice(2); } // 노출과 명도는 유지, 색상만 랜덤