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