Dataset/JS/ReactPodcastItem/podcast_item.js (125 lines of code) (raw):

import React, { PropTypes } from 'react'; import classnames from 'classnames'; import { Link } from 'react-router'; import { sanitize, highlight, formatPubDate, formatListenDate } from './utils'; import { ButtonGroup, Button, Panel, Label, } from 'react-bootstrap'; import Icon from './icon'; import Image from './image'; const Buttons = props => { const { podcast } = props; return ( <ButtonGroup style={{ float: 'right' }}> <Button title={ podcast.isPlaying ? 'Stop' : 'Play' } onClick={props.togglePlayer} ><Icon icon={ podcast.isPlaying ? 'stop' : 'play' } /> </Button> <Button download title="Download this podcast" className="btn btn-default" href={podcast.enclosureUrl} ><Icon icon="download" /></Button> {props.isLoggedIn ? <Button onClick={props.toggleBookmark} title={podcast.isBookmarked ? 'Remove bookmark' : 'Add to bookmarks'} ><Icon icon={podcast.isBookmarked ? 'bookmark' : 'bookmark-o'} /> </Button> : ''} </ButtonGroup> ); }; Buttons.propTypes = { isLoggedIn: PropTypes.bool.isRequired, podcast: PropTypes.object.isRequired, toggleBookmark: PropTypes.func.isRequired, togglePlayer: PropTypes.func.isRequired, }; export default function PodcastItem(props) { const { podcast, showChannel, showExpanded, toggleDetail, isLoggedIn, searchQuery, showImage, } = props; const channelUrl = `/channel/${podcast.channelId}/`; const podcastUrl = `/podcast/${podcast.id}/`; const image = podcast.image || '/static/podcast.png'; const playedAt = isLoggedIn && podcast.lastPlayedAt ? <div className="text-center"> <h5> <Label bsStyle="success"> Listened {formatListenDate(podcast.lastPlayedAt)} </Label> </h5> </div> : ''; let header; if (showChannel) { header = ( <div className="text-center"> <h4>{showExpanded ? podcast.title : <Link to={podcastUrl}>{podcast.title}</Link>} </h4> {playedAt} {showImage ? <div className="thumbnail"> <div className="caption text-center"> <h5><Link to={channelUrl}>{podcast.name}</Link></h5> </div> <Link to={channelUrl}> <Image src={image} errSrc="/static/podcast.png" imgProps={{ height: 60, width: 60, alt: podcast.name, }} /> </Link> </div> : <h5><Link to={channelUrl}>{podcast.name}</Link></h5> } </div> ); } else { header = ( <div className="text-center"> <h4><Link to={podcastUrl}>{podcast.title}</Link></h4> {playedAt} </div> ); } const description = sanitize(highlight(podcast.description, searchQuery)); return ( <Panel> {header} <div style={{ padding: 10 }}> <small> <time dateTime={podcast.pubDate}>{formatPubDate(podcast.pubDate)}</time>&nbsp; {podcast.source ? <a href={podcast.source} target="_blank">Source</a> : '' } </small> <Buttons {...props} /> </div> {podcast.description && !showExpanded ? <Button className="form-control" title={podcast.isShowDetail ? 'Hide details' : 'Show details'} onClick={toggleDetail} ><Icon icon={podcast.isShowDetail ? 'chevron-up' : 'chevron-down'} /> </Button> : ''} {description.__html && (podcast.isShowDetail || showExpanded) ? <p className={classnames({ lead: showExpanded, 'text-center': true })} style={{ marginTop: 20 }} dangerouslySetInnerHTML={description} /> : ''} </Panel> ); } PodcastItem.propTypes = { podcast: PropTypes.object.isRequired, isLoggedIn: PropTypes.bool.isRequired, showImage: PropTypes.bool, showChannel: PropTypes.bool.isRequired, showExpanded: PropTypes.bool, searchQuery: PropTypes.string, togglePlayer: PropTypes.func.isRequired, toggleDetail: PropTypes.func.isRequired, toggleBookmark: PropTypes.func.isRequired, };