import { Box, VStack, HStack, SpanBox } from '../../elements/LayoutPrimitives' import { LabelChip } from '../../elements/LabelChip' import type { LinkedItemCardProps } from './CardTypes' import { CoverImage } from '../../elements/CoverImage' import dayjs from 'dayjs' import relativeTime from 'dayjs/plugin/relativeTime' import { useState } from 'react' import { DotsThree, DotsThreeVertical } from 'phosphor-react' import Link from 'next/link' import { CardMenu } from '../CardMenu' dayjs.extend(relativeTime) const timeAgo = (date: string | undefined): string => { if (!date) { return '' } return dayjs(date).fromNow() } const shouldHideUrl = (url: string): boolean => { try { const origin = new URL(url).origin const hideHosts = ['https://storage.googleapis.com', 'https://omnivore.app'] if (hideHosts.indexOf(origin) != -1) { return true } } catch { console.log('invalid url item', url) } return false } const siteName = (originalArticleUrl: string, itemUrl: string): string => { if (shouldHideUrl(originalArticleUrl)) { return '' } try { return new URL(originalArticleUrl).hostname.replace(/^www\./, '') } catch {} try { return new URL(itemUrl).hostname.replace(/^www\./, '') } catch {} return '' } // Component export function LibraryListCard(props: LinkedItemCardProps): JSX.Element { const [isHovered, setIsHovered] = useState(false) const [menuOpen, setMenuOpen] = useState(false) const originText = props.item.siteName || siteName(props.item.originalArticleUrl, props.item.url) return ( { setIsHovered(true) }} onMouseLeave={() => { setIsHovered(false) }} > {timeAgo(props.item.savedAt)} {` `} {props.item.wordsCount ?? 0 > 0 ? ` • ${Math.max( 1, Math.round((props.item.wordsCount ?? 0) / 235) )} min read` : null} {props.item.readingProgressPercent ?? 0 > 0 ? ( <> {` • `} {`${Math.round(props.item.readingProgressPercent)}%`} ) : null} setMenuOpen(open)} actionHandler={props.handleAction} triggerElement={ } /> {props.item.title} {props.item.author} {props.item.author && originText && ' | '} {originText} {props.item.labels?.map(({ name, color }, index) => ( ))} ) }