Files
multica/apps/mobile/components/ui/presence-dot.tsx
YYClaw a6b83fef41 fix(agents): surface archived status for retired agents (#3608)
Retired agents (agent.archived_at set) previously read as offline across
the agent dot, hover card, detail badge, and squad member list — a
leftover online runtime row could even make them look reachable. Add a
dedicated archived presence/status that wins over every runtime/task
signal so a retired agent never reads as live or merely offline.

- Add archived to AgentAvailability and SquadMemberStatusValue unions
- Short-circuit deriveAgentPresenceDetail before runtime/task scan
- Backend deriveSquadMemberStatus returns archived instead of offline
- Render gray Archive dot/label; skip workload + reassign affordances
- en/ko/zh-Hans locale strings
2026-06-02 13:03:15 +08:00

48 lines
1.7 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Three-state presence dot — drives the agent availability indicator across
* the app. Mirror of web's AgentStatusDot (`packages/views/common/actor-avatar.tsx:188`)
* with one platform tweak: React Native has no `ring-*` utility, so the
* "cut out the avatar background" effect uses `border-2 border-background`
* (visually equivalent — 1.52 px solid border in the background colour).
*
* Color mapping is identical to the web `availabilityConfig`
* (`packages/views/agents/presence.ts:46`):
* online → success (green)
* unstable → warning (amber) — runtime offline < 5 min
* offline → muted/40 (gray)
*
* Pure presentation. Caller passes the already-derived `AgentAvailability`
* (typically from `useAgentPresence`). Loading states are handled at the
* call site — this component always renders.
*/
import { View } from "react-native";
import type { AgentAvailability } from "@multica/core/agents";
import { cn } from "@/lib/utils";
interface Props {
availability: AgentAvailability;
/** Diameter in pt. Default 8 matches the standard avatar-corner dot. */
size?: number;
}
const DOT_CLASS: Record<AgentAvailability, string> = {
online: "bg-success",
unstable: "bg-warning",
offline: "bg-muted-foreground/40",
// Retired agent (agent.archived_at set) — gray, mirrors web's archived dot
// in packages/views/agents/presence.ts.
archived: "bg-muted-foreground/40",
};
export function PresenceDot({ availability, size = 8 }: Props) {
return (
<View
style={{ width: size, height: size, borderRadius: size / 2 }}
className={cn(
"border-2 border-background",
DOT_CLASS[availability],
)}
/>
);
}