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