Use site branding on video canvas
This commit is contained in:
parent
df9a28d752
commit
3f1923701b
@ -24,6 +24,7 @@ import {
|
|||||||
Upload,
|
Upload,
|
||||||
UserRound,
|
UserRound,
|
||||||
Video,
|
Video,
|
||||||
|
Wand2,
|
||||||
X,
|
X,
|
||||||
type LucideIcon,
|
type LucideIcon,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
@ -42,8 +43,9 @@ import {
|
|||||||
useState,
|
useState,
|
||||||
} from "react";
|
} from "react";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
|
import useSWR from "swr";
|
||||||
import capturedCanvasModules from "@/artifacts/liblib-frontend-capture-ed9a2c12570a49b9a1186017b2c38b52/canvas-modules.json";
|
import capturedCanvasModules from "@/artifacts/liblib-frontend-capture-ed9a2c12570a49b9a1186017b2c38b52/canvas-modules.json";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn, fetcher } from "@/lib/utils";
|
||||||
import { canvasService } from "@/services/canvas";
|
import { canvasService } from "@/services/canvas";
|
||||||
|
|
||||||
type ActivePanel =
|
type ActivePanel =
|
||||||
@ -230,6 +232,12 @@ type LiblibVideoCanvasReplicaProps = {
|
|||||||
isLoading?: boolean;
|
isLoading?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type SiteBrandSettings = {
|
||||||
|
siteName?: string | null;
|
||||||
|
siteLogo?: string | null;
|
||||||
|
siteLogoDark?: string | null;
|
||||||
|
};
|
||||||
|
|
||||||
const capturedTools = ((capturedCanvasModules as any).tools || []) as CapturedTool[];
|
const capturedTools = ((capturedCanvasModules as any).tools || []) as CapturedTool[];
|
||||||
const capturedCounts = (capturedCanvasModules as any).counts || {};
|
const capturedCounts = (capturedCanvasModules as any).counts || {};
|
||||||
const capturedWorkflows = ((capturedCanvasModules as any).workflows || []) as WorkflowPreset[];
|
const capturedWorkflows = ((capturedCanvasModules as any).workflows || []) as WorkflowPreset[];
|
||||||
@ -1355,6 +1363,7 @@ export function LiblibVideoCanvasReplica({ canvasId, isLoading = false }: Liblib
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const canvasRef = useRef<HTMLDivElement | null>(null);
|
const canvasRef = useRef<HTMLDivElement | null>(null);
|
||||||
const dragRef = useRef<DragState | null>(null);
|
const dragRef = useRef<DragState | null>(null);
|
||||||
|
const { data: siteBrandSettings } = useSWR<SiteBrandSettings>("/api/site-settings", fetcher);
|
||||||
const [nodes, setNodes] = useState<CloneNode[]>([]);
|
const [nodes, setNodes] = useState<CloneNode[]>([]);
|
||||||
const [edges, setEdges] = useState<CloneEdge[]>([]);
|
const [edges, setEdges] = useState<CloneEdge[]>([]);
|
||||||
const [selectedNodeId, setSelectedNodeId] = useState<string | null>(null);
|
const [selectedNodeId, setSelectedNodeId] = useState<string | null>(null);
|
||||||
@ -2524,6 +2533,9 @@ export function LiblibVideoCanvasReplica({ canvasId, isLoading = false }: Liblib
|
|||||||
onStartTitleEdit={() => setIsTitleEditing(true)}
|
onStartTitleEdit={() => setIsTitleEditing(true)}
|
||||||
projectTitle={projectTitle}
|
projectTitle={projectTitle}
|
||||||
routerBack={() => router.push("/")}
|
routerBack={() => router.push("/")}
|
||||||
|
siteLogo={siteBrandSettings?.siteLogo}
|
||||||
|
siteLogoDark={siteBrandSettings?.siteLogoDark}
|
||||||
|
siteName={siteBrandSettings?.siteName}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<LeftToolbar
|
<LeftToolbar
|
||||||
@ -2694,6 +2706,9 @@ function TopBar({
|
|||||||
onStartTitleEdit,
|
onStartTitleEdit,
|
||||||
projectTitle,
|
projectTitle,
|
||||||
routerBack,
|
routerBack,
|
||||||
|
siteLogo,
|
||||||
|
siteLogoDark,
|
||||||
|
siteName,
|
||||||
}: {
|
}: {
|
||||||
draftTitle: string;
|
draftTitle: string;
|
||||||
isSaving: boolean;
|
isSaving: boolean;
|
||||||
@ -2709,6 +2724,9 @@ function TopBar({
|
|||||||
onStartTitleEdit: () => void;
|
onStartTitleEdit: () => void;
|
||||||
projectTitle: string;
|
projectTitle: string;
|
||||||
routerBack: () => void;
|
routerBack: () => void;
|
||||||
|
siteLogo?: string | null;
|
||||||
|
siteLogoDark?: string | null;
|
||||||
|
siteName?: string | null;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<header className="pointer-events-none absolute left-0 right-0 top-4 z-40 flex h-12 items-center justify-between pl-2 pr-4">
|
<header className="pointer-events-none absolute left-0 right-0 top-4 z-40 flex h-12 items-center justify-between pl-2 pr-4">
|
||||||
@ -2718,7 +2736,7 @@ function TopBar({
|
|||||||
onClick={routerBack}
|
onClick={routerBack}
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<LibTVLogo />
|
<StylizedBrandLogo siteLogo={siteLogo} siteLogoDark={siteLogoDark} siteName={siteName} />
|
||||||
</button>
|
</button>
|
||||||
<div className="h-4 w-px bg-white/14" />
|
<div className="h-4 w-px bg-white/14" />
|
||||||
{isTitleEditing ? (
|
{isTitleEditing ? (
|
||||||
@ -2895,13 +2913,39 @@ function ZoomDock({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function LibTVLogo() {
|
function StylizedBrandLogo({
|
||||||
|
siteLogo,
|
||||||
|
siteLogoDark,
|
||||||
|
siteName,
|
||||||
|
}: {
|
||||||
|
siteLogo?: string | null;
|
||||||
|
siteLogoDark?: string | null;
|
||||||
|
siteName?: string | null;
|
||||||
|
}) {
|
||||||
|
const resolvedSiteName = String(siteName || "AI Chatbot").trim() || "AI Chatbot";
|
||||||
|
const displayLogo = siteLogoDark?.trim() || siteLogo?.trim() || "";
|
||||||
|
const shouldInvertLogo = !siteLogoDark?.trim() && Boolean(siteLogo?.trim());
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<svg aria-hidden="true" className="h-6 text-white" fill="currentColor" height="17" viewBox="0 0 76.234 16.79" width="77">
|
<span className="flex min-w-0 items-center gap-2.5">
|
||||||
<path d="M16.576 16.616H0l.833-4.418H17.65z" />
|
{displayLogo ? (
|
||||||
<path d="m0 16.616 2.314-12.27h4.448l-2.316 12.27zM8.27 0h16.936l-.832 4.416H7.544z" />
|
<img
|
||||||
<path d="m25.206 0-2.314 12.27-4.512.002L20.76 0zM30.857 14.816 33.09 2.217h2.7l-1.82 10.276h4.968l-.415 2.321h-7.666zM41.025 6.328h2.556l-1.639 8.488h-2.537l1.619-8.488zm.235-2.51c0-.882.701-1.547 1.566-1.547.81 0 1.367.54 1.367 1.315 0 .882-.702 1.547-1.566 1.547-.81 0-1.367-.54-1.367-1.314M53.696 9.488c0 3.077-2.232 5.435-4.933 5.435-1.458 0-2.268-.559-2.735-1.296l-.45 1.189h-2.232L45.56 2.217h2.538l-.738 4.265c.63-.63 1.44-1.025 2.555-1.025 2.214 0 3.78 1.71 3.78 4.03m-2.574.198c0-1.422-.756-2.16-1.87-2.16-1.657 0-2.7 1.547-2.7 3.168 0 1.421.774 2.16 1.89 2.16 1.638 0 2.682-1.548 2.682-3.168zM53.929 2.217h9.934l-.395 2.321H59.85L58.03 14.814h-2.699l1.819-10.276h-3.618zM72.934 2.217h2.879l-6.497 12.599h-3.222L64.042 2.217h2.772l1.368 9.322z" />
|
alt={resolvedSiteName}
|
||||||
</svg>
|
className={cn(
|
||||||
|
"h-8 w-8 shrink-0 object-contain",
|
||||||
|
shouldInvertLogo && "brightness-0 invert"
|
||||||
|
)}
|
||||||
|
src={displayLogo}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<span className="flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-white/10">
|
||||||
|
<Wand2 className="h-4 w-4 text-white" />
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
<span className="max-w-[140px] truncate text-base font-semibold text-white">
|
||||||
|
{resolvedSiteName}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user