a tool for shared writing and social publishing
1"use client";
2import { Separator } from "./Layout";
3import { CommentTiny } from "./Icons/CommentTiny";
4import { QuoteTiny } from "./Icons/QuoteTiny";
5import { useSmoker } from "./Toast";
6import { Tag } from "./Tags";
7import { Popover } from "./Popover";
8import { TagTiny } from "./Icons/TagTiny";
9import { SpeedyLink } from "./SpeedyLink";
10
11export const InteractionPreview = (props: {
12 quotesCount: number;
13 commentsCount: number;
14 tags?: string[];
15 postUrl: string;
16 showComments: boolean | undefined;
17 share?: boolean;
18}) => {
19 let smoker = useSmoker();
20 let interactionsAvailable =
21 props.quotesCount > 0 ||
22 (props.showComments !== false && props.commentsCount > 0);
23
24 const tagsCount = props.tags?.length || 0;
25
26 return (
27 <div
28 className={`flex gap-2 text-tertiary text-sm items-center self-start`}
29 >
30 {tagsCount === 0 ? null : (
31 <>
32 <TagPopover tags={props.tags!} />
33 {interactionsAvailable || props.share ? (
34 <Separator classname="h-4!" />
35 ) : null}
36 </>
37 )}
38
39 {props.quotesCount === 0 ? null : (
40 <SpeedyLink
41 aria-label="Post quotes"
42 href={`${props.postUrl}?interactionDrawer=quotes`}
43 className="relative flex flex-row gap-1 text-sm items-center hover:text-accent-contrast hover:no-underline! text-tertiary"
44 >
45 <QuoteTiny /> {props.quotesCount}
46 </SpeedyLink>
47 )}
48 {props.showComments === false || props.commentsCount === 0 ? null : (
49 <SpeedyLink
50 aria-label="Post comments"
51 href={`${props.postUrl}?interactionDrawer=comments`}
52 className="relative flex flex-row gap-1 text-sm items-center hover:text-accent-contrast hover:no-underline! text-tertiary"
53 >
54 <CommentTiny /> {props.commentsCount}
55 </SpeedyLink>
56 )}
57 {interactionsAvailable && props.share ? (
58 <Separator classname="h-4! !min-h-0" />
59 ) : null}
60 {props.share && (
61 <>
62 <button
63 id={`copy-post-link-${props.postUrl}`}
64 className="flex gap-1 items-center hover:text-accent-contrast relative"
65 onClick={(e) => {
66 e.stopPropagation();
67 e.preventDefault();
68 let mouseX = e.clientX;
69 let mouseY = e.clientY;
70
71 if (!props.postUrl) return;
72 navigator.clipboard.writeText(`leaflet.pub${props.postUrl}`);
73
74 smoker({
75 text: <strong>Copied Link!</strong>,
76 position: {
77 y: mouseY,
78 x: mouseX,
79 },
80 });
81 }}
82 >
83 Share
84 </button>
85 </>
86 )}
87 </div>
88 );
89};
90
91const TagPopover = (props: { tags: string[] }) => {
92 return (
93 <Popover
94 className="p-2! max-w-xs"
95 trigger={
96 <div className="relative flex gap-1 items-center hover:text-accent-contrast">
97 <TagTiny /> {props.tags.length}
98 </div>
99 }
100 >
101 <TagList tags={props.tags} className="text-secondary!" />
102 </Popover>
103 );
104};
105
106const TagList = (props: { tags: string[]; className?: string }) => {
107 return (
108 <div className="flex gap-1 flex-wrap">
109 {props.tags.map((tag, index) => (
110 <Tag name={tag} key={index} className={props.className} />
111 ))}
112 </div>
113 );
114};