Last active
August 29, 2015 14:20
-
-
Save julianocomg/1998a61070e732f4ddec to your computer and use it in GitHub Desktop.
A simple realtime application using the CotaPreco/Horus
This file contains hidden or 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
/** | |
* @return {ReactComponent} | |
*/ | |
var TagInput = React.createClass({ | |
/** | |
* @return {Object} | |
*/ | |
getDefaultProps() { | |
return { | |
onAddTag: function() {} | |
}; | |
}, | |
/** | |
* @param {KeyboardEvent} e | |
*/ | |
handleSubmit(e) { | |
var input = e.target; | |
if (e.keyCode === 13) { | |
this.props.onAddTag(input.value); | |
return input.value = ''; | |
} | |
}, | |
render() { | |
return ( | |
<div className="input"> | |
<input type="text" placeholder="Type a tag" onKeyDown={this.handleSubmit}/> | |
</div> | |
); | |
} | |
}); | |
/** | |
* @return {ReactComponent} | |
*/ | |
var Tags = React.createClass({ | |
/** | |
* @return {Object} | |
*/ | |
getDefaultProps() { | |
return { | |
tags: [], | |
onRemoveTag: function() {} | |
}; | |
}, | |
/** | |
* @param {String} tag | |
*/ | |
onRemoveTag(tag) { | |
return this.props.onRemoveTag(tag); | |
}, | |
render() { | |
var tags = this.props.tags.map(function(tag) { | |
return ( | |
<span className="tag" onClick={this.onRemoveTag.bind(this, tag)}>{tag}</span> | |
); | |
}.bind(this)); | |
return ( | |
<div className="tags"> | |
{this.props.tags.length ? tags : 'Hey, add some tags here!'} | |
</div> | |
); | |
} | |
}); | |
/** | |
* @return {ReactComponent} | |
*/ | |
var Posts = React.createClass({ | |
/** | |
* @return {Object} | |
*/ | |
getDefaultProps() { | |
return { | |
posts: [], | |
tags: [] | |
}; | |
}, | |
render() { | |
var self = this; | |
var posts = this.props.posts.map(function(post) { | |
return ( | |
<li className="post"> | |
<p>{post.content}</p> | |
<span>{new Date(post.time).toString().replace('GMT-0400 (AMT)', '')}</span> | |
{post.tags.map(function(tag) { | |
var match = self.props.tags.indexOf(tag) > -1 ? ' match' : ''; | |
return ( | |
<span className={'tag' + match}>{tag}</span> | |
); | |
})} | |
</li> | |
); | |
}); | |
return ( | |
<ul className="posts"> | |
{posts} | |
</ul> | |
); | |
} | |
}); | |
/** | |
* @return {ReactComponent} | |
*/ | |
var Feed = React.createClass({ | |
/** | |
* @return {Object} | |
*/ | |
getInitialState() { | |
return { | |
connected: false, | |
tags: [], | |
posts: [] | |
}; | |
}, | |
/** | |
* @param {String} tag | |
*/ | |
onAddTag(tag) { | |
this.horus.send('ATAG ' + tag); | |
this.setState({ | |
tags: this.state.tags.concat(tag) | |
}); | |
}, | |
/** | |
* @param {String} tag | |
*/ | |
onRemoveTag(tag) { | |
this.horus.send('RTAG ' + tag); | |
var tags = this.state.tags; | |
tags.splice(tags.indexOf(tag), 1) | |
this.setState({ | |
tags: tags | |
}); | |
}, | |
/** | |
* @param {Object} post | |
*/ | |
onReceivePost(post) { | |
var posts = this.state.posts.filter(function(p) { | |
return p.content !== post.content; | |
}); | |
posts.unshift(post); | |
this.setState({ | |
posts: posts | |
}); | |
}, | |
/** | |
* @return {void} | |
*/ | |
connect() { | |
var server = React.findDOMNode(this.refs.server).value; | |
this.horus = new WebSocket(server); | |
this.horus.onopen = function() { | |
this.setState({ | |
connected: true | |
}); | |
}.bind(this); | |
this.horus.onmessage = function(post) { | |
var post = JSON.parse(post.data); | |
this.onReceivePost(post); | |
}.bind(this); | |
this.horus.onclose = function() { | |
this.setState({ | |
connected: false | |
}); | |
}.bind(this); | |
}, | |
/** | |
* @return {void} | |
*/ | |
disconnect() { | |
this.horus.close(); | |
}, | |
render() { | |
return ( | |
<div> | |
<div className="header"> | |
<h1>Horus Feed</h1> | |
<p>Choose the <strong>tags</strong> that you want to get posts!</p> | |
<div className="connection"> | |
<input | |
type="text" | |
ref="server" | |
defaultValue="ws://0.0.0.0:8000" | |
placeholder="ws://0.0.0.0:8000" | |
disabled={this.state.connected} /> | |
{!this.state.connected ? | |
<button onClick={this.connect}>Connect</button> : | |
<button onClick={this.disconnect}>Disconnect</button>} | |
</div> | |
</div> | |
<div className="app"> | |
{this.state.connected ? | |
<div> | |
<TagInput onAddTag={this.onAddTag} /> | |
<Tags tags={this.state.tags} onRemoveTag={this.onRemoveTag} /> | |
<Posts posts={this.state.posts} tags={this.state.tags} /> | |
</div> : | |
<h3>Configure and connect to the Horus server!</h3>} | |
</div> | |
</div> | |
); | |
} | |
}); | |
React.render(<Feed />, document.getElementById('feed')); |
This file contains hidden or 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
var Horus = require('horusjs'); | |
var client = new Horus('udp://0.0.0.0', 7600); | |
var tags = [ | |
'ipad', | |
'mobile', | |
'technology', | |
'apple' | |
]; | |
var post = JSON.stringify({ | |
content: "Prepare yourself for the new iPad with retina!", | |
time: Date.now(), | |
tags: tags | |
}); | |
client.send({ | |
tags: tags, | |
message: post | |
}); |
This file contains hidden or 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
<html> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Horus Feed</title> | |
<link rel="stylesheet" href="styles.css"/> | |
<script src="https://fb.me/react-0.13.2.min.js"></script> | |
<script src="https://fb.me/JSXTransformer-0.13.2.js"></script> | |
</head> | |
<body> | |
<div id="feed"></div> | |
<script src="feed.js" type="text/jsx"></script> | |
</body> | |
</html> |
This file contains hidden or 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
#feed { | |
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; | |
color: #333; | |
font-size: 14px; | |
width: 525px; | |
margin: 0 auto; | |
} | |
.header h1 { | |
font-weight: 300; | |
font-size: 40px; | |
margin-top: 50px; | |
margin-bottom: 0; | |
} | |
.header p { | |
color: #888; | |
font-weight: 300; | |
font-size: 15px; | |
margin-bottom: 0; | |
margin-top: 10px; | |
} | |
.connection { | |
float: right; | |
margin-top: -18px; | |
} | |
.connection input { | |
border-radius: 2px; | |
border: 1px solid #cdcdcd; | |
padding: 1px 5px; | |
} | |
.connection input[disabled] { | |
border-color: green; | |
color: green; | |
} | |
.connection button { | |
height: 20px; | |
margin-left: 3px; | |
} | |
.app { | |
margin-top: 60px; | |
} | |
.input, .tags { | |
display: inline-block; | |
} | |
.input input { | |
font-size: 14px; | |
width: 130px; | |
height: 30px; | |
padding: 6px 12px; | |
font-size: 14px; | |
line-height: 1.42857143; | |
color: #555; | |
background-color: #fff; | |
background-image: none; | |
border: 1px solid #ccc; | |
border-radius: 3px; | |
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075); | |
margin-right: 10px; | |
} | |
.tags .tag, .posts .post .tag { | |
display: inline; | |
padding: .2em .6em .3em; | |
font-size: 100%; | |
font-weight: 400; | |
line-height: 1; | |
color: #fff; | |
background: #337ab7; | |
text-align: center; | |
white-space: nowrap; | |
vertical-align: baseline; | |
border-radius: .25em; | |
margin: 0 5px; | |
} | |
.tags .tag:hover { | |
cursor: pointer; | |
background: #266193; | |
} | |
.posts { | |
margin-top: 10px; | |
list-style: none; | |
padding: 0; | |
border-top: 1px solid #E4E4E4; | |
padding-top: 25px; | |
} | |
.posts li:not(:first-child) { | |
border-top: 1px solid #dcdcdc; | |
} | |
.posts .post { | |
padding: 20px 0; | |
} | |
.posts .post p { | |
margin-top: 0; | |
} | |
.posts .post span { | |
color: #999; | |
} | |
.posts .post .tag { | |
padding: 2px 7px; | |
font-weight: 300; | |
padding-top: 1px; | |
font-size: 12px; | |
background: #cdcdcd; | |
} | |
.posts .post .tag.match { | |
background: #337ab7; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment