Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
118 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import fetch from 'node-fetch'; | ||
import FeedParser from 'feedparser'; | ||
|
||
export default async function fetchData(config, name) { | ||
const { title, feedUrls } = config; | ||
|
||
return Promise.all( | ||
feedUrls.map(async feedUrl => { | ||
const res = await fetch(feedUrl); | ||
return new Promise((resolve, reject) => { | ||
const feed = { name, title, meta: {}, items: [] }; | ||
res.body | ||
.on('error', error => reject(error)) | ||
.pipe(new FeedParser()) | ||
.on('error', error => reject(error)) | ||
.on('meta', meta => (feed.meta = meta)) | ||
.on('readable', function() { | ||
const stream = this; | ||
let item; | ||
while ((item = stream.read())) { | ||
feed.items.push(item); | ||
} | ||
}) | ||
.on('end', () => resolve(feed)); | ||
}); | ||
}) | ||
).then(feeds => ({ name, title, feeds })); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import React from 'react'; | ||
import classnames from 'classnames'; | ||
import timeago from 'timeago.js'; | ||
|
||
import Card from '../Card'; | ||
import './index.scss'; | ||
|
||
export class Feed extends React.Component { | ||
render() { | ||
const { name, title, feeds } = this.props; | ||
const maxItems = this.props.maxItems || 12; | ||
const seenUrls = new Set(); | ||
|
||
// Merge, de-dupe, and sort items from all feeds. | ||
const items = feeds | ||
.reduce((acc, curr) => acc.concat(curr.items), []) | ||
.filter(item => { | ||
const { link } = item; | ||
const seen = seenUrls.has(link); | ||
seenUrls.add(link); | ||
return !seen; | ||
}) | ||
.sort((a, b) => b.date.localeCompare(a.date)); | ||
|
||
return ( | ||
<Card {...this.props} className={classnames('feed', name)}> | ||
<h3>{title}</h3> | ||
<section> | ||
<ul> | ||
{items | ||
.slice(0, maxItems) | ||
.map((item, idx) => this.renderItem(item, idx))} | ||
</ul> | ||
</section> | ||
</Card> | ||
); | ||
} | ||
|
||
renderItem(item, idx) { | ||
const { title, summary, link, date } = item; | ||
const createMarkup = () => ({ __html: summary }); | ||
return ( | ||
<li key={idx} className="item"> | ||
<a className="createdAt" href={link} title={date} dateTime={date}> | ||
{timeago().format(date)} | ||
</a> | ||
<a className="link" href={link}><span className="title">{title}</span></a> | ||
{summary && <div className="content" dangerouslySetInnerHTML={createMarkup()} />} | ||
</li> | ||
); | ||
} | ||
} | ||
|
||
export default Feed; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
.card.feed { | ||
ul { | ||
list-style: none; | ||
margin: 0.5em 1em; | ||
padding: 0; | ||
li { | ||
clear: both; | ||
margin-bottom: 1.5em; | ||
padding-left: 1.75em; | ||
&::before { | ||
float: left; | ||
width: 1.75em; | ||
margin-left: -1.75em; | ||
font-style: normal; | ||
font-weight: normal; | ||
font-family: "fxemoji-symbols"; | ||
content: "\1F501"; | ||
} | ||
a { | ||
font-weight: bold; | ||
} | ||
.createdAt { | ||
float: right; | ||
font-weight: normal; | ||
white-space: nowrap; | ||
padding: 0 0 1em 1em; | ||
font-size: 0.75em; | ||
text-decoration: underline dotted; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters