diff --git a/frontend/src/contexts/ClickedElementsProvider.tsx b/frontend/src/contexts/ClickedElementsProvider.tsx index 3ec44f60..ce9aa43a 100644 --- a/frontend/src/contexts/ClickedElementsProvider.tsx +++ b/frontend/src/contexts/ClickedElementsProvider.tsx @@ -11,6 +11,7 @@ import type { SelectedComponent, } from '@/utils/previewBridge'; import type { TaskAttempt } from 'shared/types'; +import { genId } from '@/utils/id'; export interface ClickedEntry { id: string; @@ -344,7 +345,7 @@ export function ClickedElementsProvider({ return prev; // Skip consecutive duplicate } const newEntry: ClickedEntry = { - id: crypto.randomUUID(), + id: genId(), payload: sanitized, timestamp: Date.now(), dedupeKey, diff --git a/frontend/src/contexts/ReviewProvider.tsx b/frontend/src/contexts/ReviewProvider.tsx index 3d0869ef..d0855101 100644 --- a/frontend/src/contexts/ReviewProvider.tsx +++ b/frontend/src/contexts/ReviewProvider.tsx @@ -1,5 +1,6 @@ import { SplitSide } from '@git-diff-view/react'; import { createContext, useContext, useState, ReactNode } from 'react'; +import { genId } from '@/utils/id'; export interface ReviewComment { id: string; @@ -46,7 +47,7 @@ export function ReviewProvider({ children }: { children: ReactNode }) { const addComment = (comment: Omit) => { const newComment: ReviewComment = { ...comment, - id: crypto.randomUUID(), + id: genId(), }; setComments((prev) => [...prev, newComment]); }; diff --git a/frontend/src/utils/id.ts b/frontend/src/utils/id.ts new file mode 100644 index 00000000..6a0786ef --- /dev/null +++ b/frontend/src/utils/id.ts @@ -0,0 +1,6 @@ +let seq = 0; + +export function genId(): string { + seq = (seq + 1) & 0xffff; + return `${Date.now().toString(36)}-${seq.toString(36)}-${Math.random().toString(36).slice(2, 8)}`; +}