143 lines · 5.3 KB
import { useState } from "react";
import { replyReviewComment, resolveReviewThread } from "~/fns/reviews";
import { useAction } from "~/hooks/use-action";
import { ReactionBar } from "./ReactionBar";
import { Avatar, Badge, Markdown, RelativeTime } from "./ui/Primitives";
import { Button } from "./ui/Button";
import { inputClass } from "./ui/Field";
import type { getPullFiles } from "~/fns/pulls";
import { cn } from "~/utils/cn";

export type ReviewComment = Awaited<ReturnType<typeof getPullFiles>>["comments"][number];

type Props = {
  owner: string;
  repo: string;
  number: number;
  root: ReviewComment;
  replies: ReviewComment[];
  canReply: boolean;
  suggestion?: SuggestionControls;
};

export type SuggestionControls = {
  inBatch: boolean;
  pending: boolean;
  onCommit: () => void;
  onToggleBatch: () => void;
};

function rangeLabel(comment: ReviewComment): string | null {
  if (!comment.startLine) return null;
  const prefix = (side: string | null) => (side === "LEFT" ? "L" : "R");
  return `Lines ${prefix(comment.startSide)}${comment.startLine}–${prefix(comment.side)}${comment.line}`;
}

function SuggestionBar({ comment, controls }: { comment: ReviewComment; controls?: SuggestionControls }) {
  if (!comment.hasSuggestion) return null;
  if (comment.suggestionApplied) return <Badge tone="purple">Suggestion applied</Badge>;
  if (!controls) return <Badge tone="neutral">Suggested change</Badge>;
  return (