75 lines
2.0 KiB
TypeScript
75 lines
2.0 KiB
TypeScript
import { memo, useEffect } from "react";
|
|
import type { IssueInfo, PrInfo } from "@fusion/core";
|
|
import { useBadgeWebSocket } from "../hooks/useBadgeWebSocket";
|
|
import { GitHubBadge } from "./GitHubBadge";
|
|
|
|
export function pickPreferredBadge<T extends { lastCheckedAt?: string }>(
|
|
liveValue: T | null | undefined,
|
|
liveTimestamp: string | undefined,
|
|
taskValue: T | undefined,
|
|
taskTimestamp: string | undefined,
|
|
): T | undefined {
|
|
if (liveValue == null) {
|
|
return taskValue;
|
|
}
|
|
|
|
if (!liveTimestamp) {
|
|
return taskValue ?? liveValue;
|
|
}
|
|
|
|
if (!taskTimestamp || liveTimestamp >= taskTimestamp) {
|
|
return liveValue;
|
|
}
|
|
|
|
return taskValue;
|
|
}
|
|
|
|
interface TaskCardBadgeProps {
|
|
taskId: string;
|
|
prInfo?: PrInfo;
|
|
issueInfo?: IssueInfo;
|
|
updatedAt: string;
|
|
isInViewport: boolean;
|
|
projectId?: string;
|
|
}
|
|
|
|
function TaskCardBadgeComponent({ taskId, prInfo, issueInfo, updatedAt, isInViewport, projectId }: TaskCardBadgeProps) {
|
|
const { badgeUpdates, subscribeToBadge, unsubscribeFromBadge } = useBadgeWebSocket(projectId);
|
|
const hasGitHubBadge = Boolean(prInfo || issueInfo);
|
|
|
|
useEffect(() => {
|
|
if (!hasGitHubBadge || !isInViewport) {
|
|
unsubscribeFromBadge(taskId);
|
|
return;
|
|
}
|
|
|
|
subscribeToBadge(taskId);
|
|
return () => {
|
|
unsubscribeFromBadge(taskId);
|
|
};
|
|
}, [hasGitHubBadge, isInViewport, projectId, subscribeToBadge, taskId, unsubscribeFromBadge]);
|
|
|
|
const liveBadgeData = badgeUpdates.get(`${projectId ?? "default"}:${taskId}`);
|
|
const livePrInfo = pickPreferredBadge<PrInfo>(
|
|
liveBadgeData?.prInfo,
|
|
liveBadgeData?.timestamp,
|
|
prInfo,
|
|
prInfo?.lastCheckedAt ?? updatedAt,
|
|
);
|
|
const liveIssueInfo = pickPreferredBadge<IssueInfo>(
|
|
liveBadgeData?.issueInfo,
|
|
liveBadgeData?.timestamp,
|
|
issueInfo,
|
|
issueInfo?.lastCheckedAt ?? updatedAt,
|
|
);
|
|
|
|
if (!livePrInfo && !liveIssueInfo) {
|
|
return null;
|
|
}
|
|
|
|
return <GitHubBadge prInfo={livePrInfo} issueInfo={liveIssueInfo} />;
|
|
}
|
|
|
|
export const TaskCardBadge = memo(TaskCardBadgeComponent);
|
|
TaskCardBadge.displayName = "TaskCardBadge";
|