diff --git a/web/bun.lockb b/web/bun.lockb index 3a9e6d19..870ae427 100755 Binary files a/web/bun.lockb and b/web/bun.lockb differ diff --git a/web/package.json b/web/package.json index f07c77dc..53c29a8d 100644 --- a/web/package.json +++ b/web/package.json @@ -14,6 +14,7 @@ "@fontsource/roboto": "^5.0.13", "@mui/icons-material": "^5.16.7", "@mui/material": "^5.15.20", + "devalue": "^5.1.1", "firebase": "^10.12.2", "framer-motion": "^11.3.23", "notistack": "^3.0.1", diff --git a/web/src/api/chat/chat.ts b/web/src/api/chat/chat.ts index 182ee85a..c161e1ba 100644 --- a/web/src/api/chat/chat.ts +++ b/web/src/api/chat/chat.ts @@ -54,7 +54,16 @@ export async function updateMessage( export async function overview(): Promise { const res = await credFetch("GET", endpoints.roomOverview); if (res.status === 401) throw new ErrUnauthorized(); - return await res.json(); + const json: RoomOverview[] = await res.json(); + + if (!Array.isArray(json)) return json; + + for (const room of json) { + if (!room.lastMsg) continue; + room.lastMsg.createdAt = new Date(room.lastMsg.createdAt); + } + + return json; } //// DM関連 //// @@ -74,7 +83,6 @@ export async function sendDM( return res.json(); } -// WARNING: don't use this outside of api/ export async function getDM(friendId: UserID): Promise { const res = await credFetch("GET", endpoints.dmWith(friendId)); if (res.status === 401) throw new ErrUnauthorized(); @@ -82,7 +90,12 @@ export async function getDM(friendId: UserID): Promise { throw new Error( `getDM() failed: expected status code 200, got ${res.status}`, ); - return res.json(); + const json: DMRoom = await res.json(); + if (!Array.isArray(json?.messages)) return json; + for (const m of json.messages) { + m.createdAt = new Date(m.createdAt); + } + return json; } ////グループチャット関連//// diff --git a/web/src/hooks/useSWR.ts b/web/src/hooks/useSWR.ts index 0ce481af..83d3906d 100644 --- a/web/src/hooks/useSWR.ts +++ b/web/src/hooks/useSWR.ts @@ -1,3 +1,4 @@ +import { parse, stringify } from "devalue"; import { useCallback, useEffect, useState } from "react"; import type { ZodSchema } from "zod"; @@ -72,15 +73,16 @@ export function useSWR( const result = schema.safeParse(data); if (!result.success) { console.error( - `WARNING: useSWR: UNEXPECTED ZOD PARSE ERROR: Schema Parse Error: ${result.error.message}`, + `useSWR: Schema Parse Error | in incoming data | at schema ${CACHE_KEY} | Error: ${result.error.message}`, ); + console.log("data:", data); } setState({ data: data, current: "success", error: null, }); - localStorage.setItem(CACHE_KEY, JSON.stringify(data)); + localStorage.setItem(CACHE_KEY, stringify(data)); } catch (e) { setState({ data: null, @@ -92,7 +94,7 @@ export function useSWR( const write = useCallback( (data: T) => { - localStorage.setItem(CACHE_KEY, JSON.stringify(data)); + localStorage.setItem(CACHE_KEY, stringify(data)); }, [CACHE_KEY], ); @@ -115,10 +117,16 @@ function loadOldData( const oldData = localStorage.getItem(CACHE_KEY); if (oldData) { try { - const data = JSON.parse(oldData); - const parse = schema.safeParse(data); - if (!parse.success) - console.error(`useSWR: zodParseError: ${parse.error}`); + const data = parse(oldData); + const parsed = schema.safeParse(data); + if (!parsed.success) { + console.error( + `useSWR: zodParseError | in stale data | at schema ${CACHE_KEY} | ${parsed.error}`, + ); + console.log("data:", data); + // because loading old data isn't critical to the application and wrong stale data may cause several problems, + throw ""; + } return { current: "stale", data,