Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
99 lines
3.3 KiB
TypeScript
99 lines
3.3 KiB
TypeScript
import { motion } from "framer-motion";
|
|
import type { AgentGUIAgentAvatarPresentation } from "./model/agentGuiAgentAvatarPresentation";
|
|
import { isBetaAgentProvider } from "../../shared/managedAgentProviders";
|
|
import chassisAssetUrl from "../../app/renderer/assets/icons/agent-vinyl-player-chassis.png";
|
|
import tonearmAssetUrl from "../../app/renderer/assets/icons/agent-vinyl-tonearm.png";
|
|
import betaTagAssetUrl from "../../app/renderer/assets/icons/agent-vinyl-beta-tag.svg";
|
|
import { AgentGUIOwnerAvatar } from "./AgentGUIOwnerAvatar";
|
|
|
|
interface AgentGUIVinylPlayerProps {
|
|
selectedAgent: AgentGUIAgentAvatarPresentation | null;
|
|
isPlaying: boolean;
|
|
}
|
|
|
|
/**
|
|
* Directly ported from the retro-vinyl-player reference component and scaled
|
|
* by the stylesheet for the compact AgentGUI hero slot.
|
|
*/
|
|
export function AgentGUIVinylPlayer({
|
|
selectedAgent,
|
|
isPlaying
|
|
}: AgentGUIVinylPlayerProps): React.JSX.Element {
|
|
const selectedAgentCover = selectedAgent?.iconUrl ?? null;
|
|
const showBetaBadge = isBetaAgentProvider(selectedAgent?.provider);
|
|
|
|
return (
|
|
<div className="agent-gui-vinyl-player" aria-hidden="true">
|
|
{showBetaBadge ? (
|
|
<img
|
|
className="agent-gui-vinyl-player__beta"
|
|
src={betaTagAssetUrl}
|
|
alt=""
|
|
/>
|
|
) : null}
|
|
<img
|
|
className="agent-gui-vinyl-player__chassis"
|
|
src={chassisAssetUrl}
|
|
alt=""
|
|
/>
|
|
<div className="agent-gui-vinyl-player__indicator">
|
|
<div
|
|
className={`agent-gui-vinyl-player__indicator-light${
|
|
isPlaying ? " agent-gui-vinyl-player__indicator-light--playing" : ""
|
|
}`}
|
|
>
|
|
<span />
|
|
<span />
|
|
<span />
|
|
</div>
|
|
</div>
|
|
<div className="agent-gui-vinyl-player__platter">
|
|
<div className="agent-gui-vinyl-player__platter-inner">
|
|
<div
|
|
className={`agent-gui-vinyl-player__record${
|
|
isPlaying ? " agent-gui-vinyl-player__record--playing" : ""
|
|
}`}
|
|
>
|
|
{Array.from({ length: 18 }, (_, index) => (
|
|
<span
|
|
key={index}
|
|
className="agent-gui-vinyl-player__groove"
|
|
style={{ inset: `${10 + index * 4.5}px` }}
|
|
/>
|
|
))}
|
|
<span className="agent-gui-vinyl-player__reflection" />
|
|
<span className="agent-gui-vinyl-player__label">
|
|
{selectedAgentCover ? (
|
|
<img src={selectedAgentCover} alt="" />
|
|
) : null}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<img
|
|
className="agent-gui-vinyl-player__tonearm"
|
|
src={tonearmAssetUrl}
|
|
alt=""
|
|
/>
|
|
<div className="agent-gui-vinyl-player__power-control">
|
|
<motion.span
|
|
className="agent-gui-vinyl-player__lever"
|
|
animate={{ rotate: isPlaying ? 25 : -25 }}
|
|
transition={{ type: "spring", stiffness: 200, damping: 15 }}
|
|
/>
|
|
</div>
|
|
<div className="agent-gui-vinyl-player__tone-control">
|
|
<span />
|
|
<span>◦</span>
|
|
</div>
|
|
{selectedAgent?.badge?.iconUrl ? (
|
|
<AgentGUIOwnerAvatar
|
|
className="agent-gui-vinyl-player__owner-badge"
|
|
iconUrl={selectedAgent.badge.iconUrl}
|
|
label={selectedAgent.badge.label}
|
|
/>
|
|
) : null}
|
|
</div>
|
|
);
|
|
}
|