feat: add special effect for Ultra mode

This commit is contained in:
Henry Li
2026-02-08 23:22:51 +08:00
parent fdd25c1bb8
commit d36fbcdfc1
2 changed files with 115 additions and 90 deletions

View File

@@ -53,103 +53,113 @@ export function SubtaskCard({
className={cn("relative w-full gap-2 rounded-lg border py-0", className)} className={cn("relative w-full gap-2 rounded-lg border py-0", className)}
open={!collapsed} open={!collapsed}
> >
<div
className={cn(
"ambilight z-[-1]",
task.status === "in_progress" ? "enabled" : "",
)}
></div>
{task.status === "in_progress" && ( {task.status === "in_progress" && (
<ShineBorder <>
borderWidth={1.5} <ShineBorder
shineColor={["#A07CFE", "#FE8FB5", "#FFBE7B"]} borderWidth={1.5}
/> shineColor={["#A07CFE", "#FE8FB5", "#FFBE7B"]}
/>
</>
)} )}
<div className="flex w-full items-center justify-between p-0.5"> <div className="bg-background/95 flex w-full flex-col rounded-lg">
<Button <div className="flex w-full items-center justify-between p-0.5">
className="w-full items-start justify-start text-left" <Button
variant="ghost" className="w-full items-start justify-start text-left"
onClick={() => setCollapsed(!collapsed)} variant="ghost"
> onClick={() => setCollapsed(!collapsed)}
<div className="flex w-full items-center justify-between"> >
<ChainOfThoughtStep <div className="flex w-full items-center justify-between">
className="font-normal" <ChainOfThoughtStep
label={ className="font-normal"
task.status === "in_progress" ? ( label={
<Shimmer duration={3} spread={3}> task.status === "in_progress" ? (
{task.description} <Shimmer duration={3} spread={3}>
</Shimmer> {task.description}
) : ( </Shimmer>
task.description ) : (
) task.description
} )
icon={<ClipboardListIcon />} }
></ChainOfThoughtStep> icon={<ClipboardListIcon />}
<div className="flex items-center gap-1"> ></ChainOfThoughtStep>
{collapsed && ( <div className="flex items-center gap-1">
<div {collapsed && (
className={cn( <div
"text-muted-foreground flex items-center gap-1 text-xs font-normal", className={cn(
task.status === "failed" ? "text-red-500 opacity-67" : "", "text-muted-foreground flex items-center gap-1 text-xs font-normal",
)} task.status === "failed" ? "text-red-500 opacity-67" : "",
> )}
{icon}
<FlipDisplay
className="pb-1"
uniqueKey={task.latestMessage?.id ?? ""}
> >
{task.status === "in_progress" && {icon}
task.latestMessage && <FlipDisplay
hasToolCalls(task.latestMessage) className="pb-1"
? explainLastToolCall(task.latestMessage, t) uniqueKey={task.latestMessage?.id ?? ""}
: t.subtasks[task.status]} >
</FlipDisplay> {task.status === "in_progress" &&
</div> task.latestMessage &&
)} hasToolCalls(task.latestMessage)
<ChevronUp ? explainLastToolCall(task.latestMessage, t)
className={cn( : t.subtasks[task.status]}
"text-muted-foreground size-4", </FlipDisplay>
!collapsed ? "" : "rotate-180", </div>
)} )}
/> <ChevronUp
className={cn(
"text-muted-foreground size-4",
!collapsed ? "" : "rotate-180",
)}
/>
</div>
</div> </div>
</div> </Button>
</Button> </div>
</div> <ChainOfThoughtContent className="px-4 pb-4">
<ChainOfThoughtContent className="px-4 pb-4"> {task.prompt && (
{task.prompt && (
<ChainOfThoughtStep
label={
<Streamdown {...streamdownPluginsWithWordAnimation}>
{task.prompt}
</Streamdown>
}
></ChainOfThoughtStep>
)}
{task.status === "in_progress" &&
task.latestMessage &&
hasToolCalls(task.latestMessage) && (
<ChainOfThoughtStep
label={t.subtasks.in_progress}
icon={<Loader2Icon className="size-4 animate-spin" />}
>
{explainLastToolCall(task.latestMessage, t)}
</ChainOfThoughtStep>
)}
{task.status === "completed" && (
<>
<ChainOfThoughtStep
label={t.subtasks.completed}
icon={<CheckCircleIcon className="size-4" />}
></ChainOfThoughtStep>
<ChainOfThoughtStep <ChainOfThoughtStep
label={ label={
<Streamdown {...streamdownPlugins}>{task.result}</Streamdown> <Streamdown {...streamdownPluginsWithWordAnimation}>
{task.prompt}
</Streamdown>
} }
></ChainOfThoughtStep> ></ChainOfThoughtStep>
</> )}
)} {task.status === "in_progress" &&
{task.status === "failed" && ( task.latestMessage &&
<ChainOfThoughtStep hasToolCalls(task.latestMessage) && (
label={<div className="text-red-500">{task.error}</div>} <ChainOfThoughtStep
icon={<XCircleIcon className="size-4 text-red-500" />} label={t.subtasks.in_progress}
></ChainOfThoughtStep> icon={<Loader2Icon className="size-4 animate-spin" />}
)} >
</ChainOfThoughtContent> {explainLastToolCall(task.latestMessage, t)}
</ChainOfThoughtStep>
)}
{task.status === "completed" && (
<>
<ChainOfThoughtStep
label={t.subtasks.completed}
icon={<CheckCircleIcon className="size-4" />}
></ChainOfThoughtStep>
<ChainOfThoughtStep
label={
<Streamdown {...streamdownPlugins}>{task.result}</Streamdown>
}
></ChainOfThoughtStep>
</>
)}
{task.status === "failed" && (
<ChainOfThoughtStep
label={<div className="text-red-500">{task.error}</div>}
icon={<XCircleIcon className="size-4 text-red-500" />}
></ChainOfThoughtStep>
)}
</ChainOfThoughtContent>
</div>
</ChainOfThought> </ChainOfThought>
); );
} }

View File

@@ -316,9 +316,16 @@
} }
} }
.ambilight {
pointer-events: none;
opacity: 0;
transition: opacity 1s ease-in-out;
}
.ambilight:before, .ambilight:before,
.ambilight:after { .ambilight:after {
content: ""; content: "";
pointer-events: none;
position: absolute; position: absolute;
left: 0; left: 0;
top: 0; top: 0;
@@ -339,9 +346,17 @@
width: 100%; width: 100%;
height: 100%; height: 100%;
border-radius: 10px; border-radius: 10px;
opacity: 0.75;
z-index: -1; z-index: -1;
animation: ambilight 60s ease-in-out infinite; animation: ambilight 40s ease-in-out infinite;
}
.ambilight.enabled {
opacity: 1;
}
.dark .ambilight:before,
.dark .ambilight:after {
opacity: 0.85;
} }
@keyframes ambilight { @keyframes ambilight {