a tool for shared writing and social publishing
at feature/recommend 122 lines 3.7 kB view raw
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};