Javascript is all about
Reactive programming thrives on these events
So what is Reactive programming?
JavaScript
JavaScript
View Layer
Data Layer
React
RxJS
React
RxJS
The View Layer
Reacting to Username Changes
Everything is a component pure function
<!-- app.js -->
<div className="row">
<ChatRoster
onCurrentUserChange={this.onCurrentUserChange}
users={this.state.users}
currentUser={this.state.currentUser}
lastMessage={this.state.lastMessage} />
{
currentUser
?
<ChatBox
currentUser={this.state.currentUser}
myUsername={this.state.myUsername}
onMessageSent={this.onMessageSent}
messages= {this.state.messages[currentUser]} />
:
<div />
}
</div>
<ChatRoster />
<ChatBox />
Reacting to Username Changes
Use the props
<!-- chat-roster.js -->
<div className="list-group">
{
this.props.users.map(function(user) {
var unreadNotifications = that.state.unreadNotifications[user];
return (
<a data-user={user}
className={"list-group-item" + (user === currentUser ? ' active' : '')}
onClick={that.onUserSelect}
key={user}>
{user}
{unreadNotifications ?
<span className="badge">{unreadNotifications}</span> :
<div />}
</a>
)
})
}
</div>
The Data Layer
Functionality
Online Users
var appInitStream = ChatServer.initStream;
var connectionsStream = ChatServer.connections()
.map(function(username) {return {op: 'Add', username: username}});
var disconnectionsStream = ChatServer.disconnections()
.map(function(username) {return {op: 'Remove', username: username}});
var usernameChangeStream = ChatServer.usernameChanges()
.map(function(change) {
return _.extend(change, {op: 'Change'});
})
var userEventsStream = Rx.Observable
.merge(connectionsStream, disconnectionsStream, usernameChangeStream);
var onlineUsersStream = appInitStream.pluck('users')
.merge(userEventsStream)
.scan(function(users, ev) {
switch (ev.op) {
case 'Add':
return users.concat(ev.username);
case 'Remove':
return _.without(users, ev.username);
case 'Change':
users[users.indexOf(ev.old_username)] = ev.new_username;
return users;
}
return users;
});
Functionality
Typing
var isTypingStream = ChatServer
.typing()
.filter(function(user) {return user == that.props.currentUser})
.map(function() {return true});
var notTypingStream = isTypingStream
.debounce(1500)
.map(function() {return false});
var typingStream = Rx.Observable
.merge(isTypingStream, notTypingStream);
typingStream.forEach(function(isTyping) {
that.setState({typing: isTyping})
});
Functionality
In conclusion...
We think we acheived:
Questions ?
Fin.