From 4a298d205b28343a4b0547bb4907ea24e2a22484 Mon Sep 17 00:00:00 2001 From: Stringadmin Date: Tue, 9 Jun 2026 12:02:30 +0800 Subject: [PATCH] chore: reduce frontend lint warnings --- scripts/dynamic-analysis-v2.mjs | 11 +++++--- scripts/dynamic-analysis.mjs | 6 ++--- scripts/static-analysis.mjs | 3 +-- src/App.tsx | 26 ------------------- src/components/AppShell.tsx | 3 --- src/components/NotFoundPage.tsx | 1 - src/components/OnboardingTour.tsx | 2 +- src/components/toast/toastStore.ts | 2 +- src/features/assets/AssetsPage.tsx | 2 +- src/features/canvas/canvasAssetPersistence.ts | 6 ++++- src/features/canvas/canvasComponents.tsx | 7 ----- src/features/canvas/canvasToolPanels.tsx | 23 +--------------- src/features/canvas/canvasUtils.ts | 19 +++++++++----- .../canvas/canvasWorkflowExecution.ts | 2 +- src/features/canvas/useCanvasGeneration.ts | 2 +- src/features/canvas/useCanvasNodeDrag.ts | 2 +- .../character-mix/CharacterMixPage.tsx | 1 - .../digital-human/DigitalHumanPage.tsx | 2 -- src/features/ecommerce/EcommercePage.tsx | 18 +------------ .../ecommerce/EcommerceVideoWorkspace.tsx | 11 +++----- src/features/ecommerce/ecommerceTemplates.ts | 2 +- src/features/home/HomePage.tsx | 13 +--------- src/features/home/ScriptReviewVisual.tsx | 1 - src/features/home/ToolboxSection.tsx | 2 +- .../image-workbench/ImageWorkbenchPage.tsx | 3 --- src/features/profile/ProfilePage.tsx | 26 +++++++++++++++++++ .../ResolutionUpscalePage.tsx | 3 +-- .../script-tokens/ScriptTokensPage.tsx | 12 +++------ src/features/script-tokens/TokenUsagePage.tsx | 2 -- .../size-template/SizeTemplatePage.tsx | 1 - .../workbench/ConversationSidebar.tsx | 1 - .../workbench/workbenchReferenceUtils.ts | 9 ++++--- src/stores/useGenerationStore.ts | 12 --------- src/utils/errorReporting.ts | 2 +- src/utils/mentionTrigger.ts | 2 +- 35 files changed, 82 insertions(+), 158 deletions(-) diff --git a/scripts/dynamic-analysis-v2.mjs b/scripts/dynamic-analysis-v2.mjs index 5d43054..92a5216 100644 --- a/scripts/dynamic-analysis-v2.mjs +++ b/scripts/dynamic-analysis-v2.mjs @@ -27,7 +27,6 @@ console.log(' 1. MODULE DEPENDENCY GRAPH ANALYSIS'); console.log('═══════════════════════════════════════════════'); const importMap = new Map(); // file -> [imports] -const importedBy = new Map(); // file -> [importers] for (const r of results) { const imports = []; @@ -71,10 +70,13 @@ function findCircular(file, visited = new Set(), path = []) { } } } +for (const file of importMap.keys()) { + findCircular(file); +} // Check high-fanin files (imported by many) const fanIn = new Map(); -for (const [file, imports] of importMap) { +for (const imports of importMap.values()) { for (const imp of imports) { const key = imp.replace(/\[dynamic\]/, ''); fanIn.set(key, (fanIn.get(key) || 0) + 1); @@ -101,7 +103,7 @@ for (const [file, count] of sortedFanOut) { // Dynamic imports analysis (lazy loading effectiveness) console.log('\n--- Lazy Loading (Dynamic Imports) ---'); let dynamicImports = 0, staticImports = 0; -for (const [file, imports] of importMap) { +for (const imports of importMap.values()) { for (const imp of imports) { if (imp.startsWith('[dynamic]')) dynamicImports++; else staticImports++; @@ -177,6 +179,9 @@ for (const r of results) { if (noDeps > 0) { console.log(` [RENDER-COST] ${r.file}: ${noDeps} useEffect(s) run EVERY render`); } + if (emptyDeps > 0) { + console.log(` [MOUNT-EFFECT] ${r.file}: ${emptyDeps} useEffect(s) run on mount only`); + } } // ─── 4. Zustand Store Analysis ─── diff --git a/scripts/dynamic-analysis.mjs b/scripts/dynamic-analysis.mjs index ae8106e..7a9e873 100644 --- a/scripts/dynamic-analysis.mjs +++ b/scripts/dynamic-analysis.mjs @@ -3,7 +3,7 @@ * Measures: page load, bundle sizes, memory, rendering, network. */ import { chromium } from 'playwright'; -import { readFileSync, readdirSync, statSync } from 'fs'; +import { readdirSync, statSync } from 'fs'; import { join } from 'path'; const DIST = join(import.meta.dirname, '..', 'dist'); @@ -187,7 +187,7 @@ async function runtimeAnalysis() { const allElements = document.querySelectorAll('*'); const tagCounts = {}; let maxDepth = 0; - let totalNodes = allElements.length; + const totalNodes = allElements.length; allElements.forEach(el => { const tag = el.tagName.toLowerCase(); @@ -297,7 +297,7 @@ console.log('╔═════════════════════ console.log('║ OmniAI Web Preview - Performance Analysis ║'); console.log('╚═══════════════════════════════════════════════╝'); -const bundleResult = analyzeBundles(); +analyzeBundles(); await runtimeAnalysis(); console.log('\n═══════════════════════════════════════════════'); diff --git a/scripts/static-analysis.mjs b/scripts/static-analysis.mjs index afa32f9..220c574 100644 --- a/scripts/static-analysis.mjs +++ b/scripts/static-analysis.mjs @@ -1,4 +1,4 @@ -import { readdirSync, readFileSync, statSync } from 'fs'; +import { readdirSync, readFileSync } from 'fs'; import { join, relative } from 'path'; const SRC = join(import.meta.dirname, '..', 'src'); @@ -114,7 +114,6 @@ for (const r of results) { console.log('\n=== HIGH COMPLEXITY: Deep nesting ==='); for (const r of results) { const lines = r.content.split('\n'); - let maxIndent = 0; for (let i = 0; i < lines.length; i++) { const line = lines[i]; if (line.trim() === '') continue; diff --git a/src/App.tsx b/src/App.tsx index 8b62cc9..e107f40 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -295,7 +295,6 @@ function App() { openDeleteProject: openDeleteProjectModal, closeDeleteProject: closeDeleteProjectModal, setDeleteProjectSubmitting, - clearProjectState, } = useProjectStore(useShallow((s) => ({ projects: s.projects, projectsLoaded: s.projectsLoaded, @@ -310,7 +309,6 @@ function App() { openDeleteProject: s.openDeleteProject, closeDeleteProject: s.closeDeleteProject, setDeleteProjectSubmitting: s.setDeleteProjectSubmitting, - clearProjectState: s.clearProjectState, }))); // Task store @@ -349,7 +347,6 @@ function App() { setBackendHealth, markNotificationRead, markAllNotificationsRead, - clearAppState, } = useAppStore(useShallow((s) => ({ usage: s.usage, runtimeNotifications: s.runtimeNotifications, @@ -370,7 +367,6 @@ function App() { setBackendHealth: s.setBackendHealth, markNotificationRead: s.markNotificationRead, markAllNotificationsRead: s.markAllNotificationsRead, - clearAppState: s.clearAppState, }))); const [ecommerceEverMounted, setEcommerceEverMounted] = useState(false); @@ -1104,28 +1100,6 @@ function App() { [handleSetView, setImageWorkbenchTool], ); - const renderAdminOnlyPage = useCallback( - (content: React.ReactNode) => { - if (isAdminAccount(session)) return content; - - return ( -
- -
-
- 功能内测中 -

暂未开放

-

敬请期待,该功能还在开发中。

-
-
-
- ); - }, - [session], - ); - const PUBLIC_VIEWS = PUBLIC_VIEW_SET; useEffect(() => { diff --git a/src/components/AppShell.tsx b/src/components/AppShell.tsx index a130343..8efa584 100644 --- a/src/components/AppShell.tsx +++ b/src/components/AppShell.tsx @@ -10,7 +10,6 @@ import NotificationCenter from "./NotificationCenter"; import BetaApplicationModal from "./BetaApplicationModal"; import { AnimatedPanel } from "./AnimatedPanel"; import AdminMonitor from "./AdminMonitor"; -import CookieConsentBanner from "./CookieConsentBanner"; import { loadRechargeModal, type RechargeModalComponent } from "./RechargeModal/loadRechargeModal"; import { ShellIcon } from "./ShellIcon"; import { loadDarkGreenTheme } from "../styles/loadDarkGreenTheme"; @@ -76,7 +75,6 @@ function AppShell({ session, usage, notifications, - backendHealth, workspaceExpanded, onSelectView, onLogout, @@ -85,7 +83,6 @@ function AppShell({ onMarkAllNotificationsRead, children, }: AppShellProps) { - const activePackage = session?.user.activePackages?.[0]; const profileRef = useRef(null); const submenuHideTimerRef = useRef(null); const [profileOpen, setProfileOpen] = useState(false); diff --git a/src/components/NotFoundPage.tsx b/src/components/NotFoundPage.tsx index 0d57245..0912cdb 100644 --- a/src/components/NotFoundPage.tsx +++ b/src/components/NotFoundPage.tsx @@ -1,5 +1,4 @@ import { HomeOutlined } from "@ant-design/icons"; -import { useCallback } from "react"; import "../styles/pages/not-found.css"; interface NotFoundPageProps { diff --git a/src/components/OnboardingTour.tsx b/src/components/OnboardingTour.tsx index 2e6703c..0e79782 100644 --- a/src/components/OnboardingTour.tsx +++ b/src/components/OnboardingTour.tsx @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useMemo, useRef, useState, type CSSProperties } from "react"; +import { useCallback, useEffect, useRef, useState } from "react"; import { createPortal } from "react-dom"; import { CloseOutlined, LeftOutlined, RightOutlined } from "@ant-design/icons"; import "../styles/components/onboarding.css"; diff --git a/src/components/toast/toastStore.ts b/src/components/toast/toastStore.ts index f014179..f0e418a 100644 --- a/src/components/toast/toastStore.ts +++ b/src/components/toast/toastStore.ts @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useRef, useState } from "react"; +import { useEffect, useState } from "react"; export type ToastType = "success" | "error" | "info"; diff --git a/src/features/assets/AssetsPage.tsx b/src/features/assets/AssetsPage.tsx index 1b50d4f..f74b66a 100644 --- a/src/features/assets/AssetsPage.tsx +++ b/src/features/assets/AssetsPage.tsx @@ -10,7 +10,7 @@ import { SearchOutlined, UserOutlined, } from "@ant-design/icons"; -import { useCallback, useEffect, useMemo, useRef, useState, type ChangeEvent, type DragEvent, type ReactElement } from "react"; +import { useCallback, useEffect, useMemo, useRef, useState, type DragEvent, type ReactElement } from "react"; import "../../styles/pages/assets.css"; import { assetClient, type ServerAssetItem } from "../../api/assetClient"; import { aiGenerationClient } from "../../api/aiGenerationClient"; diff --git a/src/features/canvas/canvasAssetPersistence.ts b/src/features/canvas/canvasAssetPersistence.ts index 12e9079..115e328 100644 --- a/src/features/canvas/canvasAssetPersistence.ts +++ b/src/features/canvas/canvasAssetPersistence.ts @@ -106,7 +106,11 @@ function blobToDataUrl(blob: Blob): Promise { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => { - typeof reader.result === "string" ? resolve(reader.result) : reject(new Error("Unable to read canvas result")); + if (typeof reader.result === "string") { + resolve(reader.result); + } else { + reject(new Error("Unable to read canvas result")); + } }; reader.onerror = () => reject(reader.error || new Error("Unable to read canvas result")); reader.readAsDataURL(blob); diff --git a/src/features/canvas/canvasComponents.tsx b/src/features/canvas/canvasComponents.tsx index 5f9cd98..0902272 100644 --- a/src/features/canvas/canvasComponents.tsx +++ b/src/features/canvas/canvasComponents.tsx @@ -1,17 +1,10 @@ import { - CopyOutlined, - DeleteOutlined, - DownloadOutlined, DownOutlined, ExpandOutlined, MutedOutlined, PauseCircleOutlined, - PictureOutlined, PlayCircleOutlined, - ReloadOutlined, - SaveOutlined, SoundOutlined, - ThunderboltOutlined, } from "@ant-design/icons"; import { useEffect, useRef, useState, type ChangeEvent, type MouseEvent } from "react"; import type { CanvasOption } from "./canvasTypes"; diff --git a/src/features/canvas/canvasToolPanels.tsx b/src/features/canvas/canvasToolPanels.tsx index 02afbf7..0d08086 100644 --- a/src/features/canvas/canvasToolPanels.tsx +++ b/src/features/canvas/canvasToolPanels.tsx @@ -146,26 +146,6 @@ export function CanvasInpaintPanel({ imageUrl, onComplete }: CanvasToolPanelProp ctx.fill(); }; - const getMaskDataUrl = (): string => { - const canvas = canvasRef.current!; - const maskCanvas = document.createElement("canvas"); - maskCanvas.width = canvas.width; - maskCanvas.height = canvas.height; - const srcCtx = canvas.getContext("2d")!; - const maskCtx = maskCanvas.getContext("2d")!; - const imgData = srcCtx.getImageData(0, 0, canvas.width, canvas.height); - const maskData = maskCtx.createImageData(canvas.width, canvas.height); - for (let i = 0; i < imgData.data.length; i += 4) { - const hasColor = imgData.data[i + 3] > 10; - maskData.data[i] = hasColor ? 255 : 0; - maskData.data[i + 1] = hasColor ? 255 : 0; - maskData.data[i + 2] = hasColor ? 255 : 0; - maskData.data[i + 3] = 255; - } - maskCtx.putImageData(maskData, 0, 0); - return maskCanvas.toDataURL("image/png"); - }; - const handleInpaint = useCallback(async () => { if (!imageUrl || !prompt) { toast.error("请输入重绘提示词"); @@ -174,7 +154,6 @@ export function CanvasInpaintPanel({ imageUrl, onComplete }: CanvasToolPanelProp setLoading(true); cancelRef.current = false; try { - const maskDataUrl = getMaskDataUrl(); const { taskId } = await aiGenerationClient.createImageEditTask({ imageUrl, function: "inpaint", @@ -218,4 +197,4 @@ export function CanvasInpaintPanel({ imageUrl, onComplete }: CanvasToolPanelProp ); -} \ No newline at end of file +} diff --git a/src/features/canvas/canvasUtils.ts b/src/features/canvas/canvasUtils.ts index 3161984..08a2ab6 100644 --- a/src/features/canvas/canvasUtils.ts +++ b/src/features/canvas/canvasUtils.ts @@ -1,5 +1,5 @@ import type { CSSProperties } from "react"; -import { aiGenerationClient, type AiTaskStatus } from "../../api/aiGenerationClient"; +import type { AiTaskStatus } from "../../api/aiGenerationClient"; import type { ServerCommunityCase } from "../../api/communityClient"; import { waitForTask } from "../../api/taskSubscription"; import type { WebCanvasWorkflow } from "../../types"; @@ -22,7 +22,6 @@ import type { CanvasVideoMode, } from "./canvasTypes"; import { - assetLibraryCategories, assetTypePromptLabel, canvasNodeDefaultSizes, canvasNodeMaxSizes, @@ -194,7 +193,7 @@ export function resolveWorkflowImageModel(node: WebCanvasWorkflow["nodes"][numbe return defaultImageModel; } -export function resolveWorkflowVideoModel(node: WebCanvasWorkflow["nodes"][number], workflowModel: string) { +export function resolveWorkflowVideoModel(node: WebCanvasWorkflow["nodes"][number], _workflowModel: string) { const raw = getWorkflowNodeMetadataString(node, "model"); const storedModel = toPixverseDisplayModel(toViduDisplayModel(toHappyHorseDisplayModel(raw))); if (hasCanvasOptionValue(videoModelOptions, storedModel)) return storedModel; @@ -242,7 +241,11 @@ export function blobToDataUrl(blob: Blob) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => { - typeof reader.result === "string" ? resolve(reader.result) : reject(new Error("Unable to read canvas image")); + if (typeof reader.result === "string") { + resolve(reader.result); + } else { + reject(new Error("Unable to read canvas image")); + } }; reader.onerror = () => reject(reader.error || new Error("Unable to read canvas image")); reader.readAsDataURL(blob); @@ -253,7 +256,9 @@ export async function waitForImageTaskResult(taskId: string, onStatus?: (status: const resultUrl = await waitForTask(taskId, { kind: "image", onProgress: (e) => { - onStatus?.({ taskId, status: e.status, progress: e.progress, resultUrl: e.resultUrl ?? undefined, error: e.error ?? undefined } as AiTaskStatus); + if (onStatus) { + onStatus({ taskId, status: e.status, progress: e.progress, resultUrl: e.resultUrl ?? undefined, error: e.error ?? undefined } as AiTaskStatus); + } }, }); if (!resultUrl) throw new Error("生成任务已完成,但服务器没有返回结果地址,请稍后重试"); @@ -264,7 +269,9 @@ export async function waitForVideoTaskResult(taskId: string, onStatus?: (status: const resultUrl = await waitForTask(taskId, { kind: "video", onProgress: (e) => { - onStatus?.({ taskId, status: e.status, progress: e.progress, resultUrl: e.resultUrl ?? undefined, error: e.error ?? undefined } as AiTaskStatus); + if (onStatus) { + onStatus({ taskId, status: e.status, progress: e.progress, resultUrl: e.resultUrl ?? undefined, error: e.error ?? undefined } as AiTaskStatus); + } }, }); if (!resultUrl) throw new Error("视频生成任务已完成,但服务器没有返回结果地址,请稍后重试"); diff --git a/src/features/canvas/canvasWorkflowExecution.ts b/src/features/canvas/canvasWorkflowExecution.ts index 5f40bab..211509a 100644 --- a/src/features/canvas/canvasWorkflowExecution.ts +++ b/src/features/canvas/canvasWorkflowExecution.ts @@ -90,7 +90,7 @@ export function buildCanvasVideoTaskInput(workflow: WebCanvasWorkflow, nodeId: s const params = context.node.params || {}; const referenceUrls = context.imageReferences.map((item) => item.url); const displayModel = toHappyHorseDisplayModel(String(params.model || workflow.settings.model || "happyhorse-1.0")); - let model = resolveVideoRequestModel({ model: displayModel, referenceUrls }); + const model = resolveVideoRequestModel({ model: displayModel, referenceUrls }); return { title: context.node.label || "视频节点生成", type: "video", diff --git a/src/features/canvas/useCanvasGeneration.ts b/src/features/canvas/useCanvasGeneration.ts index 8af13ba..5f5b135 100644 --- a/src/features/canvas/useCanvasGeneration.ts +++ b/src/features/canvas/useCanvasGeneration.ts @@ -1,4 +1,4 @@ -import { type Dispatch, type MutableRefObject, type SetStateAction, useEffect, useRef, useState } from "react"; +import { type Dispatch, type SetStateAction, useEffect, useRef, useState } from "react"; import type { CanvasImageGenerationState, CanvasImageNode, diff --git a/src/features/canvas/useCanvasNodeDrag.ts b/src/features/canvas/useCanvasNodeDrag.ts index eb27cb5..308f0fe 100644 --- a/src/features/canvas/useCanvasNodeDrag.ts +++ b/src/features/canvas/useCanvasNodeDrag.ts @@ -1,4 +1,4 @@ -import { type Dispatch, type MouseEvent, type MutableRefObject, type SetStateAction, useEffect, useRef, useState } from "react"; +import { type Dispatch, type MouseEvent, type MutableRefObject, type SetStateAction, useEffect, useState } from "react"; import { canvasNodeClickMoveThreshold } from "./canvasConstants"; import type { CanvasAlignGuide, diff --git a/src/features/character-mix/CharacterMixPage.tsx b/src/features/character-mix/CharacterMixPage.tsx index 05a8802..6a5121a 100644 --- a/src/features/character-mix/CharacterMixPage.tsx +++ b/src/features/character-mix/CharacterMixPage.tsx @@ -13,7 +13,6 @@ import { RightOutlined, ScissorOutlined, SwapOutlined, - ThunderboltOutlined, VideoCameraOutlined, } from "@ant-design/icons"; import { useCallback, useEffect, useRef, useState, type DragEvent } from "react"; diff --git a/src/features/digital-human/DigitalHumanPage.tsx b/src/features/digital-human/DigitalHumanPage.tsx index c2e1925..abe7d34 100644 --- a/src/features/digital-human/DigitalHumanPage.tsx +++ b/src/features/digital-human/DigitalHumanPage.tsx @@ -14,7 +14,6 @@ import { RightOutlined, ScissorOutlined, SwapOutlined, - ThunderboltOutlined, UserOutlined, } from "@ant-design/icons"; import { useCallback, useEffect, useRef, useState, type DragEvent } from "react"; @@ -100,7 +99,6 @@ function DigitalHumanPage({ const [isDragging, setIsDragging] = useState(false); const imageInputRef = useRef(null); const audioInputRef = useRef(null); - const canvasDragCounterRef = useRef(0); const [isCanvasDragging, setIsCanvasDragging] = useState(false); useEffect(() => { diff --git a/src/features/ecommerce/EcommercePage.tsx b/src/features/ecommerce/EcommercePage.tsx index 159bc92..6742575 100644 --- a/src/features/ecommerce/EcommercePage.tsx +++ b/src/features/ecommerce/EcommercePage.tsx @@ -1,6 +1,5 @@ import { AppstoreOutlined, - CloudUploadOutlined, CloseOutlined, FileImageOutlined, FrownOutlined, @@ -9,7 +8,6 @@ import { MenuUnfoldOutlined, QuestionCircleOutlined, ReloadOutlined, - SettingOutlined, SkinOutlined, } from "@ant-design/icons"; import { useEffect, useMemo, useRef, useState, type CSSProperties, type ChangeEvent, type DragEvent, type ReactNode } from "react"; @@ -624,11 +622,6 @@ const tryOnModelOptions = { ethnicity: ["欧美白人", "亚洲人", "拉美裔", "非洲裔"], body: ["标准", "高挑", "微胖", "运动"], }; -const sampleResults = [ - ossAssets.ecommerce.slides.slide4, - ossAssets.ecommerce.generated, - ossAssets.ecommerce.slides.slide5, -]; const productSetAssets = ossAssets.ecommerce.productSet; const productSetPreviewCards = [ { id: "main", label: "01 主图 (白底/合规)", src: productSetAssets.main }, @@ -701,14 +694,6 @@ function readImageDimensions(src: string): Promise<{ width: number; height: numb }); } -const blobToDataUrl = (blob: Blob): Promise => - new Promise((resolve, reject) => { - const reader = new FileReader(); - reader.onload = () => resolve(String(reader.result || "")); - reader.onerror = () => reject(reader.error || new Error("文件读取失败")); - reader.readAsDataURL(blob); - }); - async function createUploadedImageItems(files: File[], limit: number, prefix: string): Promise { const selectedFiles = Array.from(files).slice(0, limit); const stamp = Date.now(); @@ -1702,7 +1687,6 @@ function ProductClonePage(_props: ProductClonePageProps = {}) { } const generatedUrls: string[] = []; - const stamp = Date.now(); for (const countKey of cloneSetCountKeys) { if (imageAbortRef.current.current) break; @@ -2039,7 +2023,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) { ); }; - const resetTask = () => { + const _resetTask = () => { setSetImages([]); setProductSetRequirement(""); setProductSetOutput("video"); diff --git a/src/features/ecommerce/EcommerceVideoWorkspace.tsx b/src/features/ecommerce/EcommerceVideoWorkspace.tsx index efc1dfd..bf69688 100644 --- a/src/features/ecommerce/EcommerceVideoWorkspace.tsx +++ b/src/features/ecommerce/EcommerceVideoWorkspace.tsx @@ -1,4 +1,4 @@ -import { Fragment, useCallback, useEffect, useMemo, useRef, useState } from "react"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import "../../styles/pages/ecommerce-video.css"; import { CloseOutlined, @@ -14,7 +14,6 @@ import { import { runVideoPlan, renderSceneImage, renderScene, buildSceneTasks, saveVideoHistory } from "./ecommerceVideoService"; import { PLAN_STEP_LABELS, - PLAN_STEPS_DISPLAY, type EcommerceVideoStage, type EcommerceVideoSceneTask, type EcommerceVideoPlanProgress, @@ -29,7 +28,6 @@ import { useGenerationTasks } from "../../hooks/useGenerationTasks"; import { saveEcommerceVideoState, loadEcommerceVideoState, - clearEcommerceVideoState, } from "./ecommerceVideoKeepalive"; interface EcommerceVideoWorkspaceProps { @@ -298,7 +296,7 @@ export default function EcommerceVideoWorkspace({ }, 3000); }; - const handleDownload = async (url: string) => { + const _handleDownload = async (url: string) => { try { await saveToolResultToLocal({ url, name: `ecommerce-video-${Date.now()}`, type: "video", @@ -310,7 +308,7 @@ export default function EcommerceVideoWorkspace({ } }; - const handleSaveAsset = async (url: string) => { + const _handleSaveAsset = async (url: string) => { try { const result = await addToolResultToAssetLibrary({ url, name: `电商短视频-${Date.now()}.mp4`, description: "电商广告视频生成结果", @@ -596,9 +594,6 @@ export default function EcommerceVideoWorkspace({ const sourceImage = sourceImageUrls[0] || planResult?.imageUrls[0] || productImageDataUrls[0] || ""; const flowHasStarted = stage !== "idle" || completedSteps.length > 0; const flowMeta = `${platform} / ${aspectRatio} / ${durationSeconds}s / ${resolution}`; - const hasImaging = stage === "imaging" || stage === "imaged" || stage === "rendering" || stage === "completed" || stage === "partial_failed"; - const hasRendering = stage === "rendering" || stage === "completed" || stage === "partial_failed"; - const visiblePlanSteps = PLAN_STEPS_DISPLAY.filter((s) => completedSteps.includes(s)); return (
diff --git a/src/features/ecommerce/ecommerceTemplates.ts b/src/features/ecommerce/ecommerceTemplates.ts index 6f96ea9..b186961 100644 --- a/src/features/ecommerce/ecommerceTemplates.ts +++ b/src/features/ecommerce/ecommerceTemplates.ts @@ -19,7 +19,7 @@ const [ ecommerceCarouselImage2, ecommerceCarouselImage3, ecommerceCarouselImage4, - ecommerceCarouselImage5, + , ecommerceCarouselImage6, ] = ossAssets.ecommerce.templateCases; const ecommerceCarouselGenerated = ossAssets.ecommerce.generated; diff --git a/src/features/home/HomePage.tsx b/src/features/home/HomePage.tsx index 2c27050..dc3d8c5 100644 --- a/src/features/home/HomePage.tsx +++ b/src/features/home/HomePage.tsx @@ -1,6 +1,5 @@ import { ArrowRightOutlined, - DashboardOutlined, FileSearchOutlined, PlayCircleOutlined, PlusOutlined, @@ -9,7 +8,6 @@ import { } from "@ant-design/icons"; import { Fragment, useCallback, useEffect, useMemo, useRef, useState, type CSSProperties } from "react"; import type { WebViewKey, WebImageWorkbenchTool } from "../../types"; -import { useScrollEntrance } from "../../hooks/useScrollEntrance"; import { ossAssets } from "../../data/ossAssets"; import "../../styles/pages/home.css"; import WelcomeSplash from "./WelcomeSplash"; @@ -17,15 +15,6 @@ import ToolboxSection from "./ToolboxSection"; import ScriptReviewShowcase from "./ScriptReviewShowcase"; import ModelGenerationShowcase from "./ModelGenerationShowcase"; -function ScrollEntrance({ children, className, ...rest }: { children: React.ReactNode; className?: string } & React.HTMLAttributes) { - const { ref, isVisible } = useScrollEntrance(); - return ( -
- {children} -
- ); -} - const [heroImage1, heroImage2, heroImage3] = ossAssets.home.heroSlides; const { ecommerce: featureEcommerceImage, @@ -469,7 +458,7 @@ function EcommerceFeatureShowcase() { ); } -function HomePage({ onOpenGenerate, onStartOnboarding, onOpenCanvas, onOpenEcommerce, onOpenScriptReview, onOpenTokenMonitor, onSelectView, onOpenImageTool }: HomePageProps) { +function HomePage({ onOpenGenerate, onStartOnboarding, onOpenCanvas, onOpenEcommerce, onOpenScriptReview, onSelectView, onOpenImageTool }: HomePageProps) { const [splashDismissed, setSplashDismissed] = useState(() => sessionStorage.getItem("omniai:splash-seen") === "1"); const [activeSlideIndex, setActiveSlideIndex] = useState(0); const [carouselMotion, setCarouselMotion] = useState(null); diff --git a/src/features/home/ScriptReviewVisual.tsx b/src/features/home/ScriptReviewVisual.tsx index ed03861..8929fd0 100644 --- a/src/features/home/ScriptReviewVisual.tsx +++ b/src/features/home/ScriptReviewVisual.tsx @@ -14,7 +14,6 @@ function ScriptReviewVisual() { const [animated, setAnimated] = useState(false); const [activeDim, setActiveDim] = useState(null); const [score, setScore] = useState(0); - const scoreRef = useRef(0); const frameRef = useRef(null); useEffect(() => { diff --git a/src/features/home/ToolboxSection.tsx b/src/features/home/ToolboxSection.tsx index ac23134..b70a696 100644 --- a/src/features/home/ToolboxSection.tsx +++ b/src/features/home/ToolboxSection.tsx @@ -145,7 +145,7 @@ const CARDS = [ }, ]; -function ToolboxSection({ onSelectView, onOpenImageTool }: ToolboxSectionProps) { +function ToolboxSection({ onSelectView }: ToolboxSectionProps) { const handleCardClick = (targetView: WebViewKey) => { onSelectView(targetView); }; diff --git a/src/features/image-workbench/ImageWorkbenchPage.tsx b/src/features/image-workbench/ImageWorkbenchPage.tsx index 488e600..ebd74e1 100644 --- a/src/features/image-workbench/ImageWorkbenchPage.tsx +++ b/src/features/image-workbench/ImageWorkbenchPage.tsx @@ -21,7 +21,6 @@ import { ScissorOutlined, SwapOutlined, TableOutlined, - ThunderboltOutlined, } from "@ant-design/icons"; import { useCallback, useEffect, useRef, useState, type DragEvent } from "react"; import "../../styles/pages/more-tools.css"; @@ -30,7 +29,6 @@ import type { WebImageWorkbenchTool, WebViewKey } from "../../types"; import { aiGenerationClient } from "../../api/aiGenerationClient"; import { waitForTask } from "../../api/taskSubscription"; import { saveToolTaskState, loadToolTaskState, clearToolTaskState } from "../workbench/toolKeepalive"; -import { translateTaskError } from "../../utils/translateTaskError"; import { addToolResultToAssetLibrary, saveToolResultToLocal } from "../workbench/toolResultActions"; import { useCanvasDrawing } from "./useCanvasDrawing"; import CameraViewport3D from "./CameraViewport3D"; @@ -40,7 +38,6 @@ type OutputSize = "9:16" | "16:9" | "4:3" | "3:4" | "1:1"; type OutputCount = 1 | 2 | 3 | 4; const OUTPUT_SIZE_OPTIONS: OutputSize[] = ["9:16", "16:9", "4:3", "3:4", "1:1"]; -const OUTPUT_COUNT_OPTIONS: OutputCount[] = [1, 2, 3, 4]; const SIZE_TO_RATIO: Record = { "9:16": "9:16", diff --git a/src/features/profile/ProfilePage.tsx b/src/features/profile/ProfilePage.tsx index e6411e8..6eb58a9 100644 --- a/src/features/profile/ProfilePage.tsx +++ b/src/features/profile/ProfilePage.tsx @@ -1488,6 +1488,32 @@ function ProfilePage({ ) : null} + {mode === "register" ? ( + + ) : null} ) : null} diff --git a/src/features/resolution-upscale/ResolutionUpscalePage.tsx b/src/features/resolution-upscale/ResolutionUpscalePage.tsx index 5559199..5044bc4 100644 --- a/src/features/resolution-upscale/ResolutionUpscalePage.tsx +++ b/src/features/resolution-upscale/ResolutionUpscalePage.tsx @@ -21,9 +21,8 @@ import "../../styles/pages/image-workbench.css"; import { aiGenerationClient } from "../../api/aiGenerationClient"; import { waitForTask } from "../../api/taskSubscription"; import { saveToolTaskState, loadToolTaskState, clearToolTaskState } from "../workbench/toolKeepalive"; -import { translateTaskError } from "../../utils/translateTaskError"; import { getServerBaseUrl, isServerRequestError } from "../../api/serverConnection"; -import { summarizeUrl, formatFileSize, fileToDataUrl, wait } from "../../utils/toolPageUtils"; +import { summarizeUrl, formatFileSize, fileToDataUrl } from "../../utils/toolPageUtils"; import TaskStatusBar from "../../components/TaskStatusBar"; import BeforeAfterCompare from "../../components/BeforeAfterCompare"; import { addToolResultToAssetLibrary, saveToolResultToLocal } from "../workbench/toolResultActions"; diff --git a/src/features/script-tokens/ScriptTokensPage.tsx b/src/features/script-tokens/ScriptTokensPage.tsx index 52a8ec6..55591d8 100644 --- a/src/features/script-tokens/ScriptTokensPage.tsx +++ b/src/features/script-tokens/ScriptTokensPage.tsx @@ -1,12 +1,6 @@ import { - BarChartOutlined, CheckCircleFilled, CloseOutlined, - CopyOutlined, - DownloadOutlined, - FileTextOutlined, - LoadingOutlined, - ThunderboltOutlined, UploadOutlined, } from "@ant-design/icons"; import { useEffect, useRef, useState, type ChangeEvent, type DragEvent, type KeyboardEvent } from "react"; @@ -264,7 +258,7 @@ function getDimensionEvidence(result: EvalResult, dim: ScoreDimension): string[] return normalizeEvidenceItems(evidence, 3); } -function formatReportMarkdown(result: EvalResult, script: string): string { +function formatReportMarkdown(result: EvalResult): string { const lines: string[] = []; lines.push(`# 剧本评测报告`); lines.push(""); @@ -438,7 +432,7 @@ function ScriptTokensPage() { const handleCopyReport = async () => { if (!result) return; - const text = formatReportMarkdown(result, script); + const text = formatReportMarkdown(result); try { await navigator.clipboard.writeText(text); setCopied(true); @@ -459,7 +453,7 @@ function ScriptTokensPage() { const handleExportMarkdown = () => { if (!result) return; - const md = formatReportMarkdown(result, script); + const md = formatReportMarkdown(result); const blob = new Blob([md], { type: "text/markdown;charset=utf-8" }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); diff --git a/src/features/script-tokens/TokenUsagePage.tsx b/src/features/script-tokens/TokenUsagePage.tsx index 33dec5d..e119757 100644 --- a/src/features/script-tokens/TokenUsagePage.tsx +++ b/src/features/script-tokens/TokenUsagePage.tsx @@ -130,8 +130,6 @@ function TokenUsagePage({ loadEnterpriseUsage, loadPersonalUsage, onOpenMore, - onOpenImageTool, - onSelectView, }: TokenUsagePageProps) { const [enterpriseUsage, setEnterpriseUsage] = useState(null); const [enterpriseUsageLoading, setEnterpriseUsageLoading] = useState(false); diff --git a/src/features/size-template/SizeTemplatePage.tsx b/src/features/size-template/SizeTemplatePage.tsx index cc32122..6d156c8 100644 --- a/src/features/size-template/SizeTemplatePage.tsx +++ b/src/features/size-template/SizeTemplatePage.tsx @@ -947,7 +947,6 @@ function SizeTemplatePage({ onOpenEcommerce }: SizeTemplatePageProps) { ); const selectedPreset = filteredTemplates.find((item) => item.title === activePresetTitle) ?? filteredTemplates[0] ?? sizeTemplatePresets[0]!; - const activeGroupLabel = sizeTemplateGroups.find((item) => item.key === selectedPreset.group)?.label ?? "尺寸模板"; const platformOptions = activeGroup === "socialCn" ? socialContentPlatformOptions diff --git a/src/features/workbench/ConversationSidebar.tsx b/src/features/workbench/ConversationSidebar.tsx index 12d701d..64ec94e 100644 --- a/src/features/workbench/ConversationSidebar.tsx +++ b/src/features/workbench/ConversationSidebar.tsx @@ -1,5 +1,4 @@ import { - CloseOutlined, DeleteOutlined, EditOutlined, MenuFoldOutlined, diff --git a/src/features/workbench/workbenchReferenceUtils.ts b/src/features/workbench/workbenchReferenceUtils.ts index 016e240..42f6efb 100644 --- a/src/features/workbench/workbenchReferenceUtils.ts +++ b/src/features/workbench/workbenchReferenceUtils.ts @@ -6,7 +6,6 @@ import { type WorkbenchMode, type ReferenceKind, type ReferenceItem, - type WorkbenchOption, } from "./workbenchConstants"; import { resolvePreUploadedUrl } from "../../api/referenceUploadService"; @@ -82,7 +81,11 @@ export function fileToDataUrl(file: File) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => { - typeof reader.result === "string" ? resolve(reader.result) : reject(new Error("Unable to read reference file")); + if (typeof reader.result === "string") { + resolve(reader.result); + } else { + reject(new Error("Unable to read reference file")); + } }; reader.onerror = () => reject(reader.error || new Error("Unable to read reference file")); reader.readAsDataURL(file); @@ -208,4 +211,4 @@ export async function resolveReferenceUrls(items: ReferenceItem[]): Promise url !== null); -} \ No newline at end of file +} diff --git a/src/stores/useGenerationStore.ts b/src/stores/useGenerationStore.ts index 711aa7c..ad20197 100644 --- a/src/stores/useGenerationStore.ts +++ b/src/stores/useGenerationStore.ts @@ -1,5 +1,4 @@ import { create } from "zustand"; -import type { WebGenerationPreviewTask } from "../types"; export type QueueItemStatus = "pending" | "running" | "completed" | "failed" | "cancelled"; @@ -63,17 +62,6 @@ interface GenerationStoreState { clearTerminal: () => void; } -function hashUserId(): string { - try { - const raw = localStorage.getItem("omniai-web-session"); - if (!raw) return "anon"; - const parsed = JSON.parse(raw) as { user?: { id?: number | string } }; - return String(parsed?.user?.id || "anon"); - } catch { - return "anon"; - } -} - const initialQueue = loadPersistedQueue(); export const useGenerationStore = create((set, get) => ({ diff --git a/src/utils/errorReporting.ts b/src/utils/errorReporting.ts index c637853..a1499c3 100644 --- a/src/utils/errorReporting.ts +++ b/src/utils/errorReporting.ts @@ -10,7 +10,7 @@ interface ErrorReport { sessionId?: string; } -let reportQueue: ErrorReport[] = []; +const reportQueue: ErrorReport[] = []; let flushTimer: ReturnType | null = null; function getSessionId(): string | undefined { diff --git a/src/utils/mentionTrigger.ts b/src/utils/mentionTrigger.ts index ca74b42..3a4d3f1 100644 --- a/src/utils/mentionTrigger.ts +++ b/src/utils/mentionTrigger.ts @@ -38,7 +38,7 @@ export function detectMentionTrigger(textBeforeCursor: string): MentionTriggerMa const query = textBeforeCursor.slice(atIdx + 1); // Query must not contain spaces or punctuation that would break a mention token - if (/[\s,。、;:!??!.,;:(){}\[\]<>""''《》【】@]/.test(query)) { + if (/[\s,。、;:!??!.,;:(){}[\]<>""''《》【】@]/.test(query)) { return null; }