jparkSF / SlackOff

Inspired by Slack. SlackOff is the cherry on top. React, Redux, Express, MongoDB

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Header

Check out the live Application!

Technologies

  • Express/Node.js
  • React
  • Redux
  • MongoDB
  • Websockets (Socket.io)

The purpose of this project was to build a full stack application with the functionality and design of a currently existing website that meets predefined feature specifications. The core feature set built was Live Chat, User Authentication, Channels, Direct Messages, and Emoji reactions

Notable Features

1) Live Chat

Slack Off utilizes websockets via Socket.io to establish real-time chat. When a user submits a new message, the client emits an signal the server to broadcast a message to others who are viewing the channel.

  • When our Message component mounts, we subscribe an open connection to Socketio. We then make sure to unsubscribe it when the component will unmount.
componentWillUnmount() {
  this.props.socket.unsubscribe(`channel-${this.props.match.params.channelId}`);
}

componentDidMount() {
 this.props.socket.on('receiveMessage', (payload) => {
        this.props.fetchMessage(payload);
      });

this.props.socket.on('subscribedChannel', (payload) => {
        this.props.fetchSingleChannel(payload._id);
      });
}
  • When a user submits a message, our Node server will trigger that open connection and send a json message to it. Socket.io will then update the client instantly.
io.on('connection', (socket) => {
  socket.on('joinChannel', (payload) => {
    socket.join(payload._id);
    socket.broadcast.to(payload._id).emit('subscribedChannel', payload);
 });

2) Live Search

Using Regex and pattern matching, we were able to implement search for channels and active highlighting with each keystroke.

  findMatches(word, channels){
    return channels.filter( (channel) => {
      const regex = new RegExp(word, 'gi');
      return channel.name.match(regex);
      })
  }
render(){
    const {channel, match} = this.props;
    const regex = new RegExp(match, 'gi');
    
    const channelName = channel.name.replace(regex, ` <span class="highlight-name"> ${match} </span>`);

      return(
        <div className="search-channel-details">
          <li className="li-search-results" onClick={this.handleClick} dangerouslySetInnerHTML={{__html:channelName}} />
          <span> Created on {this.formatTime()} </span>
        </div>
    )
  }

};

3) Multiple User authentication strategies

Incorporating Passport.js authentication strategies, we were able to incorporate a traditional login (username and password) along with social media login using Google's Oauth API.

Local-Login

passport.use('local-login', new LocalStrategy({
        // by default, local strategy uses username and password, we will override with email
        usernameField : 'username',
        passwordField : 'password',
        passReqToCallback : true // allows us to pass back the entire request to the callback
    },
    function(req, username, password, done) { 

Google-Login

passport.use(
  new GoogleStrategy({
    clientID: keys.googleClientID,
    clientSecret: keys.googleClientSecret,
    callbackURL: '/auth/google/callback',
    proxy: true
  }, async (accessToken, refreshToken,profile,done) => {
    
      const existingUser = await User.findOne({ 'google.googleId': profile.id })

            if(existingUser){
              done(null, existingUser);
            } else{
                const user =  new User();
                user.google.googleId = profile.id;
                user.google.displayName = profile.displayName;

                user.save(function(err) {
                    if (err){
                      throw err;
                    } else{
                        return done(null, user);
                    }
                });
            }
        })
);

4) Error validations

Any database validation errors are caught and prompt error messages are displayed to the user.

User authentication errors validation

Create Channel errors validation

Future Plans

  • Live Notifications
  • Infinite scroll (continuous fetch)
  • Giphys and emojis

About

Inspired by Slack. SlackOff is the cherry on top. React, Redux, Express, MongoDB


Languages

Language:JavaScript 82.3%Language:CSS 15.4%Language:HTML 2.3%