Flux

Get Started

https://facebook.github.io/flux/

Framework

BUKAN

Lupakan MVC Sejenak

https://medium.com/code-cartoons/a-cartoon-guide-to-flux-6157355ab207

Cartoon Introduction to Flux

Real Time Flux Chat

+ socket.io

Real Time Flux Chat

buat file js/actions/ChatAppAction.js
var ChatAppDispatcher = require('../dispatcher/ChatAppDispatcher');
var $ = require('jquery');

var ChatStore = require('../stores/ChatStore');

var ChatAppAction = {
  sendMessage: function(data){
    ChatAppDispatcher.handleAction({
      type: 'RECEIVE_NEW_MESSAGE',
      message: data
    });
  },
  login: function(user){
    ChatAppDispatcher.handleAction({
      type: 'USER_LOGIN',
      user: user
    });
  },
  logout: function(){
    ChatAppDispatcher.handleAction({
      type: 'USER_LOGOUT',
      user: ChatStore.getCurrentUser()
    });
  }
};

module.exports = ChatAppAction;

Real Time Flux Chat

buat file js/dispatcher/ChatAppDispatcher.js
var assign = require('object-assign');
Dispatcher = require('flux').Dispatcher;


var ChatAppDispatcher = assign(new Dispatcher(), {
  handleAction: function(action){
    this.dispatch({
      action: action
    });
  }
});

module.exports = ChatAppDispatcher;

Real Time Flux Chat

buat file js/stores/ChatStore.js
var assign = require('object-assign');
var EventEmitter = require('events').EventEmitter;
var ChatAppDispatcher = require('../dispatcher/ChatAppDispatcher');


_currentUser = null;
_allUsers = [];
_messagesBag = [];


var CHANGE_EVENT = 'change';
var ChatStore = assign({}, EventEmitter.prototype, {

  // penting
  addChangeListener: function(callback){
    this.on(CHANGE_EVENT, callback);
  },
  removeChangeListener: function(callback){
    this.removeListener(CHANGE_EVENT, callback);
  },
  emitChange: function(){
    this.emit(CHANGE_EVENT);
  },



  getCurrentUser: function(){
    return _currentUser;
  },
  getAllUsers: function(){
    return _allUsers;
  },
  getAllMessage: function(){
    return _messagesBag;
  },
  addMessage: function(message){
    _messagesBag.push(message);
  },
  setCurrentUser: function(user){
    _currentUser = user;
  },
  setAllUsers: function(users){
    _allUsers = users;
  }
});


ChatStore.dispatchToken = ChatAppDispatcher.register(function(payload){
  var action = payload.action;
  switch (action.type) {
    case 'USER_LOGIN':
      ChatStore.setCurrentUser(action.user);
      ChatStore.setAllUsers([action.user]);
      ChatStore.emitChange();
      break;
    case 'USER_LOGOUT':
      ChatStore.setCurrentUser(null);
      ChatStore.setAllUsers([]);
      ChatStore.emitChange();
      break;
    case 'RECEIVE_NEW_MESSAGE':
      if(action.message.text == ''){
        return;
      }
      ChatStore.addMessage(action.message);
      ChatStore.emitChange();
      break;
    default:
    // do nothing
  }
});


module.exports = ChatStore;

Real Time Flux Chat

update file js/components/ChatApp.react.js
var React = require('react');
var PropTypes = React.PropTypes;

var Header = require('./Header.react');
var FriendList = require('./FriendList.react');
var MessageBox = require('./MessageBox.react');
var LoginBox = require('./Login.react');

var ChatStore = require('./../stores/ChatStore');
var ChatAppAction = require('./../actions/ChatAppAction');

getStateFromStore = function(){
  return {
    messagesBag: ChatStore.getAllMessage(),
    currentUser: ChatStore.getCurrentUser(),
    allUsers: ChatStore.getAllUsers()
  };
};

var ChatApp = React.createClass({
  getInitialState: function(){
    return getStateFromStore();
  },
  componentDidMount: function(){
    ChatStore.addChangeListener(this._onChange);
  },
  componentWillUnmount: function(){
    ChatStore.removeChangeListener(this._onChange);
  },
  _onChange: function(){
    this.setState(getStateFromStore());
  },
  render: function() {
    if(!this.state.currentUser){
      return (
        <div className="chat-app">
          <Header />
          <LoginBox />
        </div>
      )
    }

    return (
      <div className="chat-app">
        <Header user={this.state.currentUser} />
        <FriendList users={this.state.allUsers} />
        <MessageBox
          messages={this.state.messagesBag}
          />
      </div>
    );
  }

});

module.exports = ChatApp;

User Join Room

(LOGIN)

Real Time Flux Chat

update file js/components/Login.react.js
var React = require('react');

var ChatAppAction = require('../actions/ChatAppAction');

var Login = React.createClass({
  joinRoom: function(e){
    e.preventDefault();
    ChatAppAction.login({
      username: this.refs.username.value
    });
  },
  render: function() {
    return (
      <div className="login-box">
        <form onSubmit={this.joinRoom}>
          <input type="text" placeholder="Masukan nama panggilan kamu" ref="username"/>
        </form>
      </div>
    );
  }

});

module.exports = Login;

User Sends Message

Real Time Flux Chat

update file js/components/ComposeMessage.react.js
var React = require('react');
var PropTypes = React.PropTypes;

var ChatAppAction = require('../actions/ChatAppAction');
var ChatStore = require('../stores/ChatStore');

var ComposeMessage = React.createClass({
  sendMessage: function(e){
    e.preventDefault();
    ChatAppAction.sendMessage({
      author: ChatStore.getCurrentUser().username,
      text: this.refs.messageText.value
    });
    this.refs.messageText.value = '';
  },
  render: function() {
    return (
      <div className="compose-message">
        <form onSubmit={this.sendMessage}>
          <input type="text" placeholder="kirim pesan" ref="messageText"/>
        </form>
      </div>
    );
  }

});

module.exports = ComposeMessage;

User Logout

Real Time Flux Chat

update file components/Header.react.js
var React = require('react');


var Header = React.createClass({
  logout: function(){
    ChatAppAction.logout();
  },
  render: function() {
    logoutButton = '';
    if(this.props.user){
      logoutButton = (<a className="logout-btn" onClick={this.logout}>logout</a>)
    }
    return (
      <div className="header">
        <h2>Chat App</h2>
        {logoutButton}
        <hr />
      </div>
    );
  }

});

module.exports = Header;

Socket.io

Real Time Flux Chat

update file stores/ChatStore.react.js
var assign = require('object-assign');
var EventEmitter = require('events').EventEmitter;
var ChatAppDispatcher = require('../dispatcher/ChatAppDispatcher');


_currentUser = null;
_allUsers = [];
_messagesBag = [];

var io = require('socket.io-client');



var CHANGE_EVENT = 'change';
var ChatStore = assign({}, EventEmitter.prototype, {
  addChangeListener: function(callback){
    this.on(CHANGE_EVENT, callback);
  },
  removeChangeListener: function(callback){
    this.removeListener(CHANGE_EVENT, callback);
  },
  emitChange: function(){
    this.emit(CHANGE_EVENT);
  },
  getCurrentUser: function(){
    return _currentUser;
  },
  getAllUsers: function(){
    return _allUsers;
  },
  getAllMessage: function(){
    return _messagesBag;
  },
  addMessage: function(message){
    _messagesBag.push(message);
  },
  setCurrentUser: function(user){
    _currentUser = user;
  },
  setAllUsers: function(users){
    _allUsers = users;
  }
});

var socket = io();

socket.on('user_login', function(user){
  ChatStore.addMessage({author: 'system', text: user.username + ' has joined the room'});
  ChatStore.emitChange();
});

socket.on('user_logout', function(user){
  ChatStore.addMessage({author: 'system', text: user.username + ' has left the room'});
  ChatStore.emitChange();
});

socket.on('users_list_change', function(users){
  ChatStore.setAllUsers(users);
  ChatStore.emitChange();
});

socket.on('receive_new_message_from_server', function(message){
  if(message.text == ''){
    return;
  }
  ChatStore.addMessage(message);
  ChatStore.emitChange();
});




ChatStore.dispatchToken = ChatAppDispatcher.register(function(payload){
  var action = payload.action;
  switch (action.type) {
    case 'USER_LOGIN':
      socket.emit('user_login', action.user);
      ChatStore.setCurrentUser(action.user);
      ChatStore.emitChange();
      break;
    case 'USER_LOGOUT':
      socket.emit('user_logout', action.user);
      ChatStore.setCurrentUser(null);
      ChatStore.setAllUsers([]);
      ChatStore.emitChange();
      break;
    case 'RECEIVE_NEW_MESSAGE':
      socket.emit('receive_new_message', action.message);
      if(action.message.text == ''){
        return;
      }
      ChatStore.emitChange();
      break;
    default:
    // do nothing
  }
});


module.exports = ChatStore;

Real Time Flux Chat

untuk diamati: server.js
var express = require('express');
var app = express();
var lowdb = require('lowdb');
// var db = lowdb('server/db/todos.json');
var bodyParser = require('body-parser');
var cors = require('cors');
var uuid = require('uuid');
var assign = require('object-assign');
var _ = require('lodash');



app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
app.use(cors());
app.use(express.static(__dirname+'/'));

app.get('/', function(req, res) {
    res.sendFile(__dirname + '/index.html');
});






var server = app.listen(7067, function(){
  console.log('listening at 7067');
});

var users = [];


var io = require('socket.io').listen(server);
io.on('connection', function(socket){
  
  socket.on('user_login', function(user){
    users.push(user);

    io.emit('user_login', user);
    io.emit('users_list_change', users);
  });

  socket.on('user_logout', function(user){
    usersList = _.remove(users, function(u){
      return u.username == user.username;
    });

    io.emit('user_logout', user);
    io.emit('users_list_change', users);
  });

  socket.on('receive_new_message', function(message){
    io.emit('receive_new_message_from_server', message);
  });



});

Real Time Flux Chat

untuk diamati: actions/ChatAppAction.js
var ChatAppDispatcher = require('../dispatcher/ChatAppDispatcher');
var $ = require('jquery');

var ChatStore = require('../stores/ChatStore');

var ChatAppAction = {
  sendMessage: function(data){
    ChatAppDispatcher.handleAction({
      type: 'RECEIVE_NEW_MESSAGE',
      message: data
    });
  },
  login: function(user){
    ChatAppDispatcher.handleAction({
      type: 'USER_LOGIN',
      user: user
    });
  },
  logout: function(){
    ChatAppDispatcher.handleAction({
      type: 'USER_LOGOUT',
      user: ChatStore.getCurrentUser()
    });
  }
};

module.exports = ChatAppAction;

Real Time Flux Chat

untuk diamati: stores/ChatStore.js
var assign = require('object-assign');
var EventEmitter = require('events').EventEmitter;
var ChatAppDispatcher = require('../dispatcher/ChatAppDispatcher');


_currentUser = null;
_allUsers = [];
_messagesBag = [];


var CHANGE_EVENT = 'change';
var ChatStore = assign({}, EventEmitter.prototype, {

  // penting
  addChangeListener: function(callback){
    this.on(CHANGE_EVENT, callback);
  },
  removeChangeListener: function(callback){
    this.removeListener(CHANGE_EVENT, callback);
  },
  emitChange: function(){
    this.emit(CHANGE_EVENT);
  },



  getCurrentUser: function(){
    return _currentUser;
  },
  getAllUsers: function(){
    return _allUsers;
  },
  getAllMessage: function(){
    return _messagesBag;
  },
  addMessage: function(message){
    _messagesBag.push(message);
  },
  setCurrentUser: function(user){
    _currentUser = user;
  },
  setAllUsers: function(users){
    _allUsers = users;
  }
});


ChatStore.dispatchToken = ChatAppDispatcher.register(function(payload){
  var action = payload.action;
  switch (action.type) {
    case 'USER_LOGIN':
      ChatStore.setCurrentUser(action.user);
      ChatStore.setAllUsers([action.user]);
      ChatStore.emitChange();
      break;
    case 'USER_LOGOUT':
      ChatStore.setCurrentUser(null);
      ChatStore.setAllUsers([]);
      ChatStore.emitChange();
      break;
    case 'RECEIVE_NEW_MESSAGE':
      if(action.message.text == ''){
        return;
      }
      ChatStore.addMessage(action.message);
      ChatStore.emitChange();
      break;
    default:
    // do nothing
  }
});


module.exports = ChatStore;
Made with Slides.com