fix(web): replace Zustand device store with local useDeviceId hook
Move device ID logic from @multica/store (Zustand persist) into a simple useDeviceId hook in the web app. SSR returns empty string, client reads/writes localStorage directly — no hydration mismatch, no suppressHydrationWarning needed. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
7d326695c1
commit
5f367fb6b7
7 changed files with 27 additions and 25 deletions
|
|
@ -4,13 +4,13 @@ import { useRef } from "react";
|
|||
import { SidebarTrigger } from "@multica/ui/components/ui/sidebar";
|
||||
import { ChatInput } from "@multica/ui/components/chat-input";
|
||||
import { MemoizedMarkdown } from "@multica/ui/components/markdown";
|
||||
import { useDeviceStore } from "@multica/store";
|
||||
import { useMessages } from "../hooks/use-messages";
|
||||
import { useDeviceId } from "../hooks/use-device-id";
|
||||
import { useScrollFade } from "../hooks/use-scroll-fade";
|
||||
import { cn } from "@multica/ui/lib/utils";
|
||||
|
||||
export function Chat() {
|
||||
const deviceId = useDeviceStore((s) => s.deviceId);
|
||||
const deviceId = useDeviceId();
|
||||
const messages = useMessages();
|
||||
const mainRef = useRef<HTMLElement>(null);
|
||||
const fadeStyle = useScrollFade(mainRef);
|
||||
|
|
@ -19,8 +19,8 @@ export function Chat() {
|
|||
<div className="h-dvh flex flex-col overflow-hidden w-full">
|
||||
<header className="flex items-center gap-2 p-2">
|
||||
<SidebarTrigger />
|
||||
<span className="text-xs text-muted-foreground font-mono" suppressHydrationWarning>
|
||||
{deviceId.slice(0, 8)}
|
||||
<span className="text-xs text-muted-foreground font-mono">
|
||||
{deviceId ? deviceId.slice(0, 8) : "\u00A0"}
|
||||
</span>
|
||||
</header>
|
||||
|
||||
|
|
|
|||
19
apps/web/app/hooks/use-device-id.ts
Normal file
19
apps/web/app/hooks/use-device-id.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import { useState, useEffect } from "react"
|
||||
import { v7 as uuidv7 } from "uuid"
|
||||
|
||||
const STORAGE_KEY = "multica-device-id"
|
||||
|
||||
export function useDeviceId(): string {
|
||||
const [deviceId, setDeviceId] = useState("")
|
||||
|
||||
useEffect(() => {
|
||||
let id = localStorage.getItem(STORAGE_KEY)
|
||||
if (!id) {
|
||||
id = uuidv7()
|
||||
localStorage.setItem(STORAGE_KEY, id)
|
||||
}
|
||||
setDeviceId(id)
|
||||
}, [])
|
||||
|
||||
return deviceId
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@
|
|||
"dependencies": {
|
||||
"@multica/store": "workspace:*",
|
||||
"@multica/ui": "workspace:*",
|
||||
"uuid": "^13.0.0",
|
||||
"@hugeicons/core-free-icons": "^3.1.1",
|
||||
"@hugeicons/react": "^1.1.4",
|
||||
"next": "16.1.6",
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
"./*": "./src/*.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"uuid": "^13.0.0",
|
||||
"zustand": "catalog:"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
import { create } from 'zustand'
|
||||
import { persist } from 'zustand/middleware'
|
||||
import { v7 as uuidv7 } from 'uuid'
|
||||
|
||||
interface DeviceState {
|
||||
deviceId: string
|
||||
}
|
||||
|
||||
export const useDeviceStore = create<DeviceState>()(
|
||||
persist(
|
||||
() => ({
|
||||
deviceId: uuidv7(),
|
||||
}),
|
||||
{ name: 'multica-device' }
|
||||
)
|
||||
)
|
||||
|
|
@ -1,2 +1 @@
|
|||
export { useCounterStore } from './counter'
|
||||
export { useDeviceStore } from './device'
|
||||
|
|
|
|||
6
pnpm-lock.yaml
generated
6
pnpm-lock.yaml
generated
|
|
@ -223,6 +223,9 @@ importers:
|
|||
react-dom:
|
||||
specifier: 'catalog:'
|
||||
version: 19.2.3(react@19.2.3)
|
||||
uuid:
|
||||
specifier: ^13.0.0
|
||||
version: 13.0.0
|
||||
devDependencies:
|
||||
'@types/node':
|
||||
specifier: 'catalog:'
|
||||
|
|
@ -261,9 +264,6 @@ importers:
|
|||
|
||||
packages/store:
|
||||
dependencies:
|
||||
uuid:
|
||||
specifier: ^13.0.0
|
||||
version: 13.0.0
|
||||
zustand:
|
||||
specifier: 'catalog:'
|
||||
version: 5.0.10(@types/react@19.2.10)(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue