mirror of
https://github.com/basketikun/infinite-canvas.git
synced 2026-08-05 00:34:22 +08:00
feat(canvas): 添加视频模型配置和生成功能
- 在系统配置中新增 defaultVideoModel 字段用于设置默认视频模型 - 更新应用配置模态框以支持视频模型的选择和验证 - 修改画布节点逻辑以支持视频类型的生成配置 - 实现视频节点的生成和上传功能 - 更新模型选择器组件以支持视频模型选择 - 在管理后台设置页面添加视频模型配置选项 - 优化模型选择器的层级和交互体验 - 添加对 DeepSeek 和 GLM 模型图标的支持
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useMemo, useState } from "react";
|
||||
import { useEffect, useId, useMemo, useState } from "react";
|
||||
import { Cpu } from "lucide-react";
|
||||
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger } from "@/components/ui/select";
|
||||
@@ -18,10 +18,19 @@ type ModelPickerProps = {
|
||||
};
|
||||
|
||||
export function ModelPicker({ config, value, onChange, className, fullWidth = false, placeholder = "选择模型", onMissingConfig }: ModelPickerProps) {
|
||||
const pickerId = useId();
|
||||
const [open, setOpen] = useState(false);
|
||||
const options = useMemo(() => Array.from(new Set([value, ...config.models].filter(Boolean))), [config.models, value]);
|
||||
const current = value || "";
|
||||
|
||||
useEffect(() => {
|
||||
const closeOtherPicker = (event: Event) => {
|
||||
if ((event as CustomEvent<string>).detail !== pickerId) setOpen(false);
|
||||
};
|
||||
window.addEventListener("model-picker-open", closeOtherPicker);
|
||||
return () => window.removeEventListener("model-picker-open", closeOtherPicker);
|
||||
}, [pickerId]);
|
||||
|
||||
return (
|
||||
<Select
|
||||
open={open}
|
||||
@@ -31,6 +40,7 @@ export function ModelPicker({ config, value, onChange, className, fullWidth = fa
|
||||
onMissingConfig?.();
|
||||
return;
|
||||
}
|
||||
if (nextOpen) window.dispatchEvent(new CustomEvent("model-picker-open", { detail: pickerId }));
|
||||
setOpen(nextOpen);
|
||||
}}
|
||||
onValueChange={onChange}
|
||||
@@ -51,9 +61,11 @@ export function ModelPicker({ config, value, onChange, className, fullWidth = fa
|
||||
</SelectTrigger>
|
||||
<SelectContent
|
||||
data-canvas-no-zoom
|
||||
className="z-50 w-80 max-w-[calc(100vw-24px)] rounded-xl border border-border/70 bg-popover p-1 shadow-xl"
|
||||
className="z-[1200] w-80 max-w-[calc(100vw-24px)] rounded-xl border border-border/70 bg-popover p-1 shadow-xl"
|
||||
position="popper"
|
||||
align="start"
|
||||
side="bottom"
|
||||
sideOffset={6}
|
||||
onPointerDown={(event) => event.stopPropagation()}
|
||||
onMouseDown={(event) => event.stopPropagation()}
|
||||
>
|
||||
@@ -93,5 +105,7 @@ function resolveModelIcon(model: string) {
|
||||
if (name.includes("gemini") || name.includes("google")) return "/icons/gemini.svg";
|
||||
if (name.includes("gpt") || name.includes("openai")) return "/icons/openai.svg";
|
||||
if (name.includes("grok") || name.includes("grok")) return "/icons/grok.svg";
|
||||
if (name.includes("deepseek") || name.includes("deepseek")) return "/icons/deepseek.svg";
|
||||
if (name.includes("glm") || name.includes("glm")) return "/icons/glm.svg";
|
||||
return "";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user