140 lines · 5.5 KB
import { Popover } from "@cloudflare/kumo/components/popover";
import { SELECTED_SURFACE } from "~/ui/tones";
import { useState } from "react";
import { useQueryClient } from "@tanstack/react-query";
import { reactorsQueryKey, useReactors } from "~/hooks/use-reactors";
import { toggleReaction } from "~/fns/reactions";
import { useOptimisticMutation } from "~/hooks/use-optimistic-mutation";
import { REACTION_CONTENTS, REACTION_EMOJI, reactorsLabel } from "~/lib/reactions";
import type { ReactionContent, ReactionSubject, ReactionSummary } from "~/lib/reactions";
import { cn } from "~/utils/cn";

type Props = {
  owner: string;
  repo: string;
  subjectType: ReactionSubject;
  subjectId: string;
  reactions: ReactionSummary[];
  canReact: boolean;
};

function toggleLocally(current: ReactionSummary[], content: ReactionContent): ReactionSummary[] {
  const existing = current.find((reaction) => reaction.content === content);
  if (!existing) return [...current, { content, count: 1, viewerReacted: true }];
  const next = existing.viewerReacted
    ? { ...existing, count: existing.count - 1, viewerReacted: false }
    : { ...existing, count: existing.count + 1, viewerReacted: true };
  return current.flatMap((reaction) => (reaction.content !== content ? [reaction] : next.count > 0 ? [next] : []));
}

type PillProps = {
  target: { owner: string; repo: string; subjectType: ReactionSubject; subjectId: string; content: ReactionContent };
  reaction: ReactionSummary;
  disabled: boolean;
  onToggle: () => void;
};

function ReactionPill({ target, reaction, disabled, onToggle }: PillProps) {
  const [hovered, setHovered] = useState(false);
  const reactors = useReactors(target, hovered);
  const label = reactors.data