From 32dd65a6dbeee4689e2fbe0433c50e8bcbb4f965 Mon Sep 17 00:00:00 2001 From: kotto5 Date: Sun, 11 Feb 2024 20:26:01 +0900 Subject: [PATCH 1/5] =?UTF-8?q?[frontend]=20useState=20=E3=81=8C=20client?= =?UTF-8?q?=20component=20=E3=81=A7=E3=81=AE=E3=81=BF=E5=88=A9=E7=94=A8?= =?UTF-8?q?=E3=81=A7=E3=81=8D=E3=82=8B=E3=81=AE=E3=81=A7=20file=20?= =?UTF-8?q?=E3=82=92=E5=88=86=E3=81=91=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/app/layout.tsx | 9 ++----- frontend/app/lib/client-socket-provider.tsx | 27 +++++++++++++++------ frontend/app/onlineProviders.tsx | 20 +++++++++++++++ 3 files changed, 41 insertions(+), 15 deletions(-) create mode 100644 frontend/app/onlineProviders.tsx diff --git a/frontend/app/layout.tsx b/frontend/app/layout.tsx index c4812626..7cb937f2 100644 --- a/frontend/app/layout.tsx +++ b/frontend/app/layout.tsx @@ -3,7 +3,6 @@ import type { Metadata } from "next"; import { Inter } from "next/font/google"; import AuthProvider from "@/app/lib/client-auth-provider"; -import SocketProvider from "@/app/lib/client-socket-provider"; import { getAccessTokenPayload } from "@/app/lib/session"; // components @@ -13,7 +12,7 @@ import { Toaster } from "@/components/ui/toaster"; // ui import { getMe } from "@/app/lib/actions"; import { JwtPayload } from "@/app/lib/dtos"; -import Nav from "@/app/ui/nav"; +import { OnlineProviders } from "./onlineProviders"; const inter = Inter({ subsets: ["latin"] }); @@ -45,12 +44,8 @@ export default async function RootLayout({ disableTransitionOnChange > -
-
- + {children}
diff --git a/frontend/app/lib/client-socket-provider.tsx b/frontend/app/lib/client-socket-provider.tsx index 4324cc25..90b2b8aa 100644 --- a/frontend/app/lib/client-socket-provider.tsx +++ b/frontend/app/lib/client-socket-provider.tsx @@ -3,7 +3,14 @@ import { ToastAction } from "@/components/ui/toast"; import { useToast } from "@/components/ui/use-toast"; import { chatSocket } from "@/socket"; import Link from "next/link"; -import { useCallback, useEffect, useState } from "react"; +import { + Dispatch, + SetStateAction, + createContext, + useCallback, + useEffect, + useState, +} from "react"; import { useAuthContext } from "./client-auth"; import { DenyEvent, @@ -19,7 +26,13 @@ import { chatSocket as socket } from "@/socket"; import { useRouter } from "next/navigation"; import { usePathname } from "next/navigation"; -export default function SocketProvider() { +export const OnlineContext = createContext<{ [key: number]: number }>({}); + +export default function SocketProvider({ + setOnlineStatus, +}: { + setOnlineStatus: Dispatch>; +}) { const { toast } = useToast(); const { currentUser } = useAuthContext(); const pathName = usePathname(); @@ -117,16 +130,14 @@ export default function SocketProvider() { }); }; - const [onlineStatus, setOnlineStatus] = useState<{ [key: number]: number }>( - {}, - ); const handleOnlineStatus = (users: { userId: number; status: number }[]) => { - console.log("users", users); users.forEach((u) => { - console.log("FOO! u", u); setOnlineStatus((prev) => ({ ...prev, [u.userId]: u.status })); }); - console.log("online-status", onlineStatus); // TODO: この時点では変更されていない? + toast({ + title: "online-status", + description: JSON.stringify(users), + }); }; const showMessageToast = (message: MessageEvent) => { diff --git a/frontend/app/onlineProviders.tsx b/frontend/app/onlineProviders.tsx new file mode 100644 index 00000000..78ffc31c --- /dev/null +++ b/frontend/app/onlineProviders.tsx @@ -0,0 +1,20 @@ +"use client"; + +import { useOnlineStatus } from "./lib/hooks/useOnlineStatus"; +import SocketProvider, { OnlineContext } from "./lib/client-socket-provider"; +import Nav from "./ui/nav"; + +export function OnlineProviders({ children }: { children: React.ReactNode }) { + const { onlineStatus, setOnlineStatus } = useOnlineStatus(); + return ( + <> + +
+
+ +
+ + ); +} From bbc6f9d7a73cfd9b20a09f819bf4ee0e36188d5e Mon Sep 17 00:00:00 2001 From: kotto5 Date: Sun, 11 Feb 2024 20:27:43 +0900 Subject: [PATCH 2/5] =?UTF-8?q?[frontend]=20session.ts=20=E3=81=8C=20clien?= =?UTF-8?q?t=20component=20=E3=81=A8=E3=81=97=E3=81=A6=E8=AA=AD=E3=81=BE?= =?UTF-8?q?=E3=82=8C=E3=80=81=20cookies=20=E3=82=92=20import=20=E3=81=99?= =?UTF-8?q?=E3=82=8B=E3=81=A8=E3=81=93=E3=82=8D=E3=81=A7=E3=82=A8=E3=83=A9?= =?UTF-8?q?=E3=83=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/app/lib/session.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/app/lib/session.ts b/frontend/app/lib/session.ts index 50f56ba2..787c52ac 100644 --- a/frontend/app/lib/session.ts +++ b/frontend/app/lib/session.ts @@ -1,3 +1,4 @@ +"use server"; import * as jose from "jose"; import { cookies } from "next/headers"; import { redirect } from "next/navigation"; From 82993095025978bb2617b40c60360ad93af9f21c Mon Sep 17 00:00:00 2001 From: kotto5 Date: Sun, 11 Feb 2024 20:29:00 +0900 Subject: [PATCH 3/5] =?UTF-8?q?[frontend]=20server=20component=20=E3=81=AF?= =?UTF-8?q?=20=E5=85=A8=E3=81=A6=20async=20=E3=81=AB=E3=81=97=E3=81=AA?= =?UTF-8?q?=E3=81=91=E3=82=8C=E3=81=B0=E3=81=AA=E3=82=89=E3=81=AA=E3=81=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/app/lib/session.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/app/lib/session.ts b/frontend/app/lib/session.ts index 787c52ac..ff04d688 100644 --- a/frontend/app/lib/session.ts +++ b/frontend/app/lib/session.ts @@ -11,7 +11,7 @@ export type Session = {}; const secret = jose.base64url.decode(process.env.JWT_SECRET!); const spki = process.env.JWT_PUBLIC_KEY!; -export function setAccessToken(token: string) { +export async function setAccessToken(token: string) { cookies()?.set("token", token, { httpOnly: true, // JS cannot access secure: process.env.NODE_ENV === "production", // HTTPS only @@ -113,7 +113,7 @@ export async function getSession(): Promise { } } -export function destroySession() { +export async function destroySession() { console.log("destroySession"); cookies()?.delete("session"); } From 15990b622aca9054a431dfe13e4f1a20478487a0 Mon Sep 17 00:00:00 2001 From: kotto5 Date: Sun, 11 Feb 2024 20:32:57 +0900 Subject: [PATCH 4/5] [frontend] use context in UserList --- frontend/app/lib/hooks/useOnlineStatus.ts | 10 ++++++++++ frontend/app/ui/user/user-list.tsx | 6 ++++-- 2 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 frontend/app/lib/hooks/useOnlineStatus.ts diff --git a/frontend/app/lib/hooks/useOnlineStatus.ts b/frontend/app/lib/hooks/useOnlineStatus.ts new file mode 100644 index 00000000..b7c26840 --- /dev/null +++ b/frontend/app/lib/hooks/useOnlineStatus.ts @@ -0,0 +1,10 @@ +"use client"; + +import { useState } from "react"; + +export function useOnlineStatus() { + const [onlineStatus, setOnlineStatus] = useState<{ [key: number]: number }>( + {} + ); + return { onlineStatus, setOnlineStatus }; +} diff --git a/frontend/app/ui/user/user-list.tsx b/frontend/app/ui/user/user-list.tsx index 8619adb4..6f37de49 100644 --- a/frontend/app/ui/user/user-list.tsx +++ b/frontend/app/ui/user/user-list.tsx @@ -3,7 +3,8 @@ import type { PublicUserEntity } from "@/app/lib/dtos"; import { TooltipProvider } from "@/components/ui/tooltip"; import { Avatar, AvatarSize } from "./avatar"; -import { useEffect, useState } from "react"; +import { OnlineContext } from "@/app/lib/client-socket-provider"; +import { useContext } from "react"; export default function UserList({ users, @@ -12,6 +13,7 @@ export default function UserList({ users: PublicUserEntity[]; avatarSize: AvatarSize; }) { + const onlineStatus = useContext(OnlineContext); return (
@@ -22,7 +24,7 @@ export default function UserList({ size={avatarSize} href={`/user/${u.id}`} alt={u.name} - online={true} + online={onlineStatus[u.id] === 1} key={u.id} /> ))} From 5d86086741ae3b48c372f8be2b40b980a841eee2 Mon Sep 17 00:00:00 2001 From: kotto5 Date: Sun, 11 Feb 2024 22:02:11 +0900 Subject: [PATCH 5/5] [frontend] display uesr's online status!!! --- frontend/app/layout.tsx | 6 +++++- frontend/app/lib/hooks/useOnlineStatus.ts | 2 +- frontend/app/onlineProviders.tsx | 6 +----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/frontend/app/layout.tsx b/frontend/app/layout.tsx index 7cb937f2..2378ae03 100644 --- a/frontend/app/layout.tsx +++ b/frontend/app/layout.tsx @@ -13,6 +13,7 @@ import { Toaster } from "@/components/ui/toaster"; import { getMe } from "@/app/lib/actions"; import { JwtPayload } from "@/app/lib/dtos"; import { OnlineProviders } from "./onlineProviders"; +import Nav from "./ui/nav"; const inter = Inter({ subsets: ["latin"] }); @@ -45,7 +46,10 @@ export default async function RootLayout({ > - {children} +
+
diff --git a/frontend/app/lib/hooks/useOnlineStatus.ts b/frontend/app/lib/hooks/useOnlineStatus.ts index b7c26840..3758080d 100644 --- a/frontend/app/lib/hooks/useOnlineStatus.ts +++ b/frontend/app/lib/hooks/useOnlineStatus.ts @@ -4,7 +4,7 @@ import { useState } from "react"; export function useOnlineStatus() { const [onlineStatus, setOnlineStatus] = useState<{ [key: number]: number }>( - {} + {}, ); return { onlineStatus, setOnlineStatus }; } diff --git a/frontend/app/onlineProviders.tsx b/frontend/app/onlineProviders.tsx index 78ffc31c..11d64384 100644 --- a/frontend/app/onlineProviders.tsx +++ b/frontend/app/onlineProviders.tsx @@ -2,17 +2,13 @@ import { useOnlineStatus } from "./lib/hooks/useOnlineStatus"; import SocketProvider, { OnlineContext } from "./lib/client-socket-provider"; -import Nav from "./ui/nav"; export function OnlineProviders({ children }: { children: React.ReactNode }) { const { onlineStatus, setOnlineStatus } = useOnlineStatus(); return ( <> -
-
+ {children}