From a569775120f6a340fc0b69aed4503b44b94b540d Mon Sep 17 00:00:00 2001 From: boojack Date: Thu, 13 Aug 2026 22:45:08 +0800 Subject: [PATCH] chore(web): standardize UUID generation --- web/src/components/MemoEditor/hooks/useFileUpload.ts | 3 ++- .../MemoEditor/hooks/useInlineImageUpload.ts | 3 ++- web/src/components/Settings/AISection.tsx | 10 ++-------- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/web/src/components/MemoEditor/hooks/useFileUpload.ts b/web/src/components/MemoEditor/hooks/useFileUpload.ts index 12650e0b..35d71fe3 100644 --- a/web/src/components/MemoEditor/hooks/useFileUpload.ts +++ b/web/src/components/MemoEditor/hooks/useFileUpload.ts @@ -1,5 +1,6 @@ import { create } from "@bufbuild/protobuf"; import { useRef } from "react"; +import { v4 as uuidv4 } from "uuid"; import { useAuth } from "@/contexts/AuthContext"; import { type MotionMedia, MotionMediaFamily, MotionMediaRole, MotionMediaSchema } from "@/types/proto/api/v1/attachment_service_pb"; import { mediaMetadataService } from "../services/mediaMetadataService"; @@ -81,7 +82,7 @@ export const pairAppleLivePhotoFiles = (localFiles: LocalFile[]): LocalFile[] => const image = images[0]; const video = videos[0]; - const groupId = groupIds.get(stem) ?? `${stem}-${crypto.randomUUID()}`; + const groupId = groupIds.get(stem) ?? `${stem}-${uuidv4()}`; groupIds.set(stem, groupId); if (localFile.previewUrl === image.previewUrl) { return { ...localFile, motionMedia: buildLocalMotionMedia(groupId, MotionMediaRole.STILL) }; diff --git a/web/src/components/MemoEditor/hooks/useInlineImageUpload.ts b/web/src/components/MemoEditor/hooks/useInlineImageUpload.ts index 1de4043b..5891edad 100644 --- a/web/src/components/MemoEditor/hooks/useInlineImageUpload.ts +++ b/web/src/components/MemoEditor/hooks/useInlineImageUpload.ts @@ -1,6 +1,7 @@ import { uniqBy } from "lodash-es"; import { type RefObject, useCallback, useEffect, useRef, useState } from "react"; import { toast } from "react-hot-toast"; +import { v4 as uuidv4 } from "uuid"; import type { Attachment } from "@/types/proto/api/v1/attachment_service_pb"; import { isImage } from "@/utils/attachment"; import { useTranslate } from "@/utils/i18n"; @@ -69,7 +70,7 @@ const createJob = (localFiles: LocalFile[]): UploadJob | undefined => { const { inline, representativeIndexes } = splitInlineLocalFiles(localFiles); if (inline.length === 0) return undefined; return { - id: crypto.randomUUID(), + id: uuidv4(), entries: inline.map((localFile) => ({ localFile })), representativeIndexes, active: false, diff --git a/web/src/components/Settings/AISection.tsx b/web/src/components/Settings/AISection.tsx index 9b0e468f..3265cc90 100644 --- a/web/src/components/Settings/AISection.tsx +++ b/web/src/components/Settings/AISection.tsx @@ -3,6 +3,7 @@ import { isEqual } from "lodash-es"; import { MoreVerticalIcon, PlusIcon } from "lucide-react"; import { useEffect, useMemo, useRef, useState } from "react"; import { toast } from "react-hot-toast"; +import { v4 as uuidv4 } from "uuid"; import ConfirmDialog from "@/components/ConfirmDialog"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog"; @@ -50,13 +51,6 @@ const providerTypeOptions = [InstanceSetting_AIProviderType.OPENAI, InstanceSett const byokNotes = ["setting.ai.byok-key-note", "setting.ai.byok-storage-note", "setting.ai.byok-model-note"] as const; -const createProviderID = () => { - if (typeof crypto !== "undefined" && "randomUUID" in crypto) { - return crypto.randomUUID(); - } - return `ai-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`; -}; - const getProviderTypeLabel = (type: InstanceSetting_AIProviderType) => { return InstanceSetting_AIProviderType[type] ?? "UNKNOWN"; }; @@ -81,7 +75,7 @@ const toLocalTranscription = (config: InstanceSetting_TranscriptionConfig | unde }); const newProvider = (): LocalAIProvider => ({ - id: createProviderID(), + id: uuidv4(), title: "", type: InstanceSetting_AIProviderType.OPENAI, endpoint: "",