jsx import { css , jsx } from '@emotion/core' ; import { IconButton , Link , Tooltip , Typography } from '@material-ui/core' ; import ExpandMoreIcon from '@material-ui/icons/ExpandMore' ; import cx from 'classnames' ; import moment from 'moment' ; import React , { useState } from 'react' ; import { useMutation } from 'react-query' ; import { Link as RouterLink } from 'react-router-dom' ; import { toast } from 'react-toastify' ; import baseStyles from '../base.module.scss' ; import { Bookmark } from '../bookmark' ; import { Group , PaperListItem } from '../models' ; import { HelpTooltip } from '../utils/HelpTooltip' ; import { Latex } from '../utils/latex' ; import { arrowTooltipsClasses as arrowTooltipClasses } from '../utils/presets' ; import { QueryContext } from '../utils/QueryContext' ; import { Spacer } from '../utils/Spacer' ; import { addOrRemovePaperToGroupRequest , addRemoveGroupFromPapersListCache , OnSelectGroupProps , } from '../utils/useGroups' ; import { GroupMarkers } from './ItemGroups' ; import styles from './styles.module.scss' ; import { itemClassNames } from './utils' ; const metadataCss = css `
  margin-right: 6px;
` ; interface PapersListItemProps { paper : PaperListItem ; groups : Group [ ] ; } const SingleMetadata = ( { tooltip , icon , children } ) => { return ( < Tooltip title = { tooltip } placement = "top" arrow classes = { arrowTooltipClasses } > < Typography variant = "body2" className = "text-gray-500" > < i className = { icon } css = { metadataCss } / > { children } < /Typography> < /Tooltip>); } ; const PaperMetadata = ( { paper } ) => { const { comments_count , twitter_score , num_stars , code } = paper ; return ( < React . Fragment > < SingleMetadata tooltip = "Comments" icon = "fas fa-comments" > { comments_count || '0' } < /SingleMetadata> < Spacer size = { 16 } / > < SingleMetadata tooltip = "Collections the paper belongs to" icon = "fa fa-star" > { num_stars || '0' } < /SingleMetadata> < Spacer size = { 16 } / > < SingleMetadata tooltip = "Likes, retweets and replies" icon = "fab fa-twitter" > { twitter_score } < /SingleMetadata> { code ?. github && ( < SingleMetadata tooltip = "Github stars (by PapersWithCode)" icon = "fab fa-github" > { code ?. stars || 0 } < /SingleMetadata>)} < /React.Fragment>); } ; const ExpandPaper = ( { expanded , handleExpandClick , } ) => ( < HelpTooltip title = { expanded ? 'Close abstract' : 'Expand Abstract' } > < IconButton onClick = { handleExpandClick } aria - expanded = { expanded } aria - label = "Show more" size = "small" edge = "end" > < ExpandMoreIcon fontSize = "small" className = { cx ( 'transition-transform duration-300' , expanded ? 'transform rotate-180' : undefined ) } / > < /IconButton> < /HelpTooltip>); export const Item = ( { paper , groups } ) => { const [ expanded , setExpanded ] = useState ( false ) ; const handleExpandClick = ( e ) => { e . preventDefault ( ) ; setExpanded ( ! expanded ) ; } ; const queryContext = React . useContext ( QueryContext ) ; const [ onSelectGroup ] = useMutation ( async ( props ) => { return addOrRemovePaperToGroupRequest ( { paperId : paper . id , ... props } ) ; } , { onMutate : ( { shouldAdd , groupId } ) => { const queryKey = [ 'papers' , queryContext . query ] ; addRemoveGroupFromPapersListCache ( { queryKey , groupId , shouldAdd , paperId : paper . id } ) ; return ( ) => addRemoveGroupFromPapersListCache ( { queryKey , groupId , shouldAdd : ! shouldAdd , paperId : paper . id } ) ; } , onError : ( err , props , rollback ) => { rollback ( ) ; toast . error ( 'Failed to update collection' ) ; } , } ) ; return ( < div className = { itemClassNames } > < GroupMarkers groups = { groups } paperGroupIds = { paper . groups } / > < div className = { styles . itemTitleSection } > < Link variant = "h6" color = "textPrimary" component = { RouterLink } to = { `/paper/${ paper . id }` } > < Latex > { paper . title } < /Latex> < /Link> < Bookmark className = { styles . itemBookmark } edge = "end" paperId = { paper . id } size = { 20 } selectedGroupIds = { paper . groups } onSelectGroup = { props => { onSelectGroup ( props ) ; } } type = "list" / > < /div> < Spacer size = { 8 } / > < Typography component = "div" variant = "body2" color = "textSecondary" > { paper . authors . map ( ( author , index ) => ( < React . Fragment key = { index } > < Link component = { RouterLink } variant = "body2" color = "textSecondary" to = { `/discover/?author=${ author . name }` } > { author . name } < /Link> { index < paper . authors . length - 1 ? < React . Fragment > , & nbsp ; < /React.Fragment> : ''} < /React.Fragment>))} < /Typography> < Spacer size = { 4 } / > < Typography variant = "body2" color = "textSecondary" > { moment . utc ( paper . timePublished ) . format ( 'MMM DD, YYYY' ) } < /Typography> < Spacer size = { 12 } / > < div className = { baseStyles . centeredRow } > < PaperMetadata paper = { paper } /> < Spacer size = { 1 } grow / > < ExpandPaper { ... { expanded , handleExpandClick } } / > < /div> { expanded && ( < React . Fragment > < Typography variant = "body2" className = "pt-2" > < span className = "leading-relaxed text-gray-700" > { paper . abstract && < Latex > { paper . abstract } < /Latex>}</span > < /Typography> < /React.Fragment>)} < /div>); } ;