2016-02-03 18:04:06 +00:00
|
|
|
const $ = require("jquery");
|
|
|
|
const React = require("react");
|
|
|
|
const helper = require("javascripts/helper");
|
|
|
|
const storageAvailable = helper.storageAvailable;
|
2016-02-12 23:22:46 +00:00
|
|
|
import {MenubarMixin} from "javascripts/components/menubar";
|
2016-02-03 18:04:06 +00:00
|
|
|
|
|
|
|
const READ_ARTICLES_STORAGE = "akuh098h209ufnw";
|
2016-02-12 15:41:37 +00:00
|
|
|
const HTML_ENTITY_REGEX = /&#\d+;/;
|
2016-02-03 18:04:06 +00:00
|
|
|
|
|
|
|
const News = exports.News = React.createClass({
|
2016-02-12 23:22:46 +00:00
|
|
|
mixins: [MenubarMixin],
|
|
|
|
|
2016-02-03 18:04:06 +00:00
|
|
|
getInitialState() {
|
|
|
|
let readArticles = {};
|
|
|
|
if (storageAvailable('localStorage')) {
|
|
|
|
const raw = localStorage.getItem(READ_ARTICLES_STORAGE) || {};
|
|
|
|
let rawJson;
|
|
|
|
try {
|
|
|
|
rawJson = JSON.parse(raw);
|
|
|
|
} catch (e) {
|
|
|
|
rawJson = {};
|
|
|
|
}
|
|
|
|
readArticles = rawJson;
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
posts: [],
|
|
|
|
readArticles: readArticles
|
|
|
|
};
|
|
|
|
},
|
|
|
|
|
|
|
|
updatePosts(data) {
|
|
|
|
this.setState({
|
|
|
|
posts: data.posts.slice(0,5).map(post => {
|
|
|
|
return {
|
|
|
|
id: post.id,
|
|
|
|
url: post.url,
|
|
|
|
title: post.title
|
|
|
|
}
|
|
|
|
})
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
2016-02-12 15:41:37 +00:00
|
|
|
renderTitle(title) {
|
|
|
|
return title.replace(HTML_ENTITY_REGEX, match => {
|
|
|
|
return String.fromCharCode(match.slice(2, match.length - 1))
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
2016-02-03 18:04:06 +00:00
|
|
|
componentDidMount() {
|
|
|
|
$.getJSON("http://ns2news.org/api-json/get_recent_posts?callback=?")
|
|
|
|
.done(this.updatePosts);
|
|
|
|
},
|
|
|
|
|
|
|
|
markAsRead(post) {
|
|
|
|
const self = this;
|
|
|
|
return function (e) {
|
|
|
|
let readArticles = self.state.readArticles;
|
|
|
|
readArticles[post.id] = (new Date()).toJSON();
|
|
|
|
self.setState({readArticles: readArticles});
|
|
|
|
|
|
|
|
if (storageAvailable('localStorage')) {
|
|
|
|
localStorage.setItem(READ_ARTICLES_STORAGE, JSON.stringify(readArticles));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
hasBeenRead(post) {
|
|
|
|
return (this.state.readArticles[post.id] !== undefined);
|
|
|
|
},
|
|
|
|
|
|
|
|
render() {
|
|
|
|
const articles = this.state.posts.map(post => {
|
|
|
|
let postClass = "";
|
|
|
|
if (!this.hasBeenRead(post)) postClass += "unread";
|
|
|
|
return (
|
|
|
|
<li key={post.id}>
|
|
|
|
<a href={post.url} target="_blank" onClick={this.markAsRead(post)}
|
2016-02-12 15:41:37 +00:00
|
|
|
className={postClass}>{this.renderTitle(post.title)}</a>
|
2016-02-03 18:04:06 +00:00
|
|
|
</li>
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
const unreadArticles = this.state.posts.reduce((prev, post) => {
|
|
|
|
if (this.hasBeenRead(post)) {
|
|
|
|
return prev;
|
|
|
|
} else {
|
|
|
|
return prev + 1;
|
|
|
|
}
|
|
|
|
}, 0)
|
|
|
|
|
|
|
|
let tag;
|
|
|
|
if (unreadArticles > 0) {
|
|
|
|
tag = <span className="label label-success">{unreadArticles}</span>;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<li className={this.componentClass()}>
|
|
|
|
<a href="#" onClick={this.toggleShow}>
|
|
|
|
<i className="fa fa-newspaper-o"></i>
|
|
|
|
{tag}
|
|
|
|
</a>
|
|
|
|
<ul className="dropdown-menu">
|
2016-02-12 17:05:46 +00:00
|
|
|
<li className="header">NS2News.org</li>
|
2016-02-03 18:04:06 +00:00
|
|
|
<ul className="news-menu">
|
|
|
|
{articles}
|
|
|
|
</ul>
|
|
|
|
</ul>
|
|
|
|
</li>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
});
|