Skip to content

Commit

Permalink
Merge pull request #15 from composer22/feature/server
Browse files Browse the repository at this point in the history
Feature/server - eact demo + leave room bug on server
  • Loading branch information
composer22 committed May 11, 2015
2 parents 4b290ed + e0aa229 commit 5299602
Show file tree
Hide file tree
Showing 18 changed files with 1,402 additions and 7 deletions.
2 changes: 1 addition & 1 deletion client/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
## ChattyPantz Client Demos

Subfolders in this directory demonstrate client side connections to the Chattypantz server.
Subfolders in this directory demonstrate client side connections to the Chattypantz server. Two demos are presented using Angular.js and React.js toolkits.
11 changes: 5 additions & 6 deletions client/angular/app/scripts/controllers/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ angular.module('chattypantzApp').controller('MainCtrl', function($scope, $route,
// Error Conditions
ERR_ROOM_MANDATORY: 1001,
ERR_MAX_ROOMS_REACHED: 1002,
ERR_NICKNAME_MANDATORY: 1003,
ERR_ALREADY_JOINED: 1004,
ERR_NICKNAME_USED: 1005,
ERR_HIDDEN_NICKNAME: 1006,
ERR_NOT_IN_ROOM: 1007,
ERR_ROOM_UNAVAILABLE: 1003,
ERR_NICKNAME_MANDATORY: 1004,
ERR_ALREADY_JOINED: 1005,
ERR_NICKNAME_USED: 1006,
ERR_HIDDEN_NICKNAME: 1007,
ERR_UNKNOWN_REQUEST: 1008
}

Expand Down Expand Up @@ -104,7 +104,6 @@ angular.module('chattypantzApp').controller('MainCtrl', function($scope, $route,
$scope.$apply();
break;
case RESPONSE_TYPE.LIST_NAMES:
console.log("GOT HERE")
var users = angular.fromJson(response.list);
$scope.chat.data.users = users;
$scope.$apply();
Expand Down
34 changes: 34 additions & 0 deletions client/react/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
## ChattyPantz Client Demo - React.js

This folder contains a simple demonstration of a client connection to the server using javascript and html.

### Dependencies

* You must be connected to the internet to load CDN react.js, semnatic-ui.js, and jquery.js.
* The server should be running on localhost:6660

### Instructions

Assumption: server is up and running on localhost:6660.

If needed, you can change the API host and port endpoint in scripts/services/api.js:
```
var server = "ws://127.0.0.1:6660/v1.0/chat";
```
1. Load index.html in your browser.
2. Enter a nickname.
3. Connect to the server.

You will be placed into room "Demo". A list of user nicknames from the room will also be displayed.
NOTE: If your nickname already exists when logging into the room, you will be warned and disconnected.

4. Now, send your messages.
5. When you are done, disconnect from the server.

### Enhancements

The application doesn't demonstrate multi-room management, nor does it demonstrate the following request types:
* GET_NICKNAME: 102
* LIST_ROOMS: 103
* HIDE: 106
* UNHIDE: 107
107 changes: 107 additions & 0 deletions client/react/css/app.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/* Space out content a bit */
body {
padding-top: 20px;
padding-bottom: 20px;
}

/* Everything but the jumbotron gets side spacing for mobile first views */
.header,
.marketing,
.footer {
padding-left: 15px;
padding-right: 15px;
}

/* Custom page header */
.header {
border-bottom: 1px solid #e5e5e5;
}
/* Make the masthead heading the same height as the navigation */
.header h3 {
margin-top: 0;
margin-bottom: 0;
line-height: 40px;
padding-bottom: 19px;
}

/* Custom page footer */
.footer {
padding-top: 19px;
margin-top: 30px;
color: #777;
border-top: 1px solid #e5e5e5;
}

/* Customize container */
@media (min-width: 768px) {
.container {
max-width: 730px;
}
}
.container-narrow > hr {
margin: 30px 0;
}

/* Main marketing message and sign up button */
.jumbotron {
text-align: center;
border-bottom: 1px solid #e5e5e5;
}
.jumbotron .btn {
font-size: 21px;
padding: 14px 24px;
}

/* Supporting marketing content */
.marketing {
margin: 40px 0;
}
.marketing p + h4 {
margin-top: 28px;
}

/* Responsive: Portrait tablets and up */
@media screen and (min-width: 768px) {
/* Remove the padding we set earlier */
.header,
.marketing,
.footer {
padding-left: 0;
padding-right: 0;
}
/* Space out the masthead */
.header {
margin-bottom: 30px;
}
/* Remove the bottom border on the jumbotron for visual effect */
.jumbotron {
border-bottom: 0;
}
}


/* CUSTOM CSS */

#chat-history {
width: 100%;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
text-align: left;
overflow-y: scroll;
overflow-x: hidden;
height: 250px;
}

#connection-error {
/* text-align: center;*/
}

#online-user-list {
overflow-y: scroll;
overflow-x: hidden;
height: 150px;
text-align: left;
}


54 changes: 54 additions & 0 deletions client/react/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!-->
<html class="no-js">
<!--<![endif]-->

<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Chattypantz Client Demo</title>
<meta name="description" content="A client demo for Chattypantz Chat Server">
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/1.12.0/semantic.min.css" />
<link rel="stylesheet" href="css/app.css">
</head>

<body>
<!--[if lt IE 7]>
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
<![endif]-->
<div class="ui page grid">
<div class="ui header">
<h3 class="text-muted">ChattyPantz Client Demo</h3>
</div>
<div id="chattypantzapp"></div>
</div>

<!--[if lt IE 9]>
<script src="https://cdnjs.cloudflare.com/ajax/libs/json3/3.3.2/json3.min.js"></script>
<![endif]-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.31.0/es6-shim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/1.12.0/semantic.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.2/JSXTransformer.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.2/react-with-addons.min.js"></script>
<script src="js/libs/facebook/flux/dist/Flux.js"></script>
<script src="js/libs/joyent/node/lib/util.js"></script>
<script src="js/libs/joyent/node/lib/events.js"></script>

<!-- The application: no bundler or tools -->
<script src="js/constants/AppConstants.js"></script>
<script src="js/actions/LoginActions.js"></script>
<script src="js/actions/ConnectionActions.js"></script>
<script src="js/dispatcher/AppDispatcher.js"></script>
<script type="text/jsx" src="js/stores/LoginStore.js"></script>
<script type="text/jsx" src="js/stores/ConnectionStore.js"></script>
<script type="text/jsx" src="js/components/LoginSection.react.js"></script>
<script type="text/jsx" src="js/components/ConnectedSection.react.js"></script>
<script type="text/jsx" src="js/app.js"></script>
</body>

</html>
25 changes: 25 additions & 0 deletions client/react/js/actions/ConnectionActions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Helper functions for sending commands to the dispatcher from the Connection Form.

var ConnectionActions = {
// Send a message to the server.
send: function(message) {
AppDispatcher.dispatch({
actionType: ActionTypes.SEND_MESSAGE,
message: message
});
},

// Refresh the form elements
refresh: function() {
AppDispatcher.dispatch({
actionType: ActionTypes.REFRESH_CONNECTION
});
},

// Logout of the server.
logout: function() {
AppDispatcher.dispatch({
actionType: ActionTypes.LOGOUT
});
}
}
17 changes: 17 additions & 0 deletions client/react/js/actions/LoginActions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Helper functions for sending commands to the dispatcher from teh Login form.

var LoginActions = {
login: function(nickname) {
AppDispatcher.dispatch({
actionType: ActionTypes.LOGIN,
nickname: nickname
});
},
refresh: function(nickname, error) {
AppDispatcher.dispatch({
actionType: ActionTypes.REFRESH_LOGIN,
nickname: nickname,
error: error
});
}
}
6 changes: 6 additions & 0 deletions client/react/js/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Load initial state of the application.
React.render(
<LoginSection />,
document.getElementById("chattypantzapp")
);

106 changes: 106 additions & 0 deletions client/react/js/components/ConnectedSection.react.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// ConnectedSection is the interactive form for communication to the server once connected.
var ConnectedSection = React.createClass({
render: function() {
return(
<div id="connectedSection">
<div className="ui page grid">
<div className="twelve wide column">
<textarea id="chat-history" ref="chatHistory"></textarea>
</div>
<div className="four wide column" id="online-user-list">
<a className="ui teal ribbon label">Online Users {this.state.users.length}</a>
<br/>
{this._displayUsers()}
</div>
</div>

<form className="ui form" name="sendForm">
<div className="ui page grid">
<div className="two wide column">
<input type="submit" className="ui primary submit button disabled" ref="sendButton" value="Send!" onClick={this._handleSend}/>
</div>
<div className="eight wide column field">
<input className="message" name="messageText" type="text" onChange={this._handleMessageChange}
ref="messageBox" placeholder="Type message here..." />
</div>
<div className="two wide column">
<input type="button" className="ui mini red button" value="Quit" onClick={this._handleQuit}/>
</div>
</div>
</form>
</div>
);
},

getInitialState: function() {
return {
users: [],
history: ''
};
},

componentDidMount: function(){
ConnectionStore.addChangeListener(this._onChange);
},

componentWillUnmount: function(){
ConnectionStore.removeChangeListener(this._onChange);
},

_disableSendButton: function() {
React.findDOMNode(this.refs.sendButton).className = "ui primary submit button disabled";
},

_enableSendButton: function() {
React.findDOMNode(this.refs.sendButton).className = "ui primary submit button";
},

// callback method for store to communicate any data change.
_onChange: function() {
var csc = ConnectionStore.chat;
this.setState({
users: csc.data.users,
history: csc.data.history
});
var ch = React.findDOMNode(this.refs.chatHistory);
ch.value = this.state.history;
ch.scrollTop = ch.scrollHeight;
this.forceUpdate();
},

_displayUsers: function() {
var result = ""
return (
<div>
{this.state.users.map(function(user) {
return <span>{user}<br/></span>;
})}
</div>
);
},

// Send button pressed for message.
_handleSend: function() {
var msg = React.findDOMNode(this.refs.messageBox).value
ConnectionActions.send(msg);
React.findDOMNode(this.refs.messageBox).value = "";
this._disableSendButton();
return false;
},

// When the message field changes, check the length and disable the
// send button if it is empty.
_handleMessageChange: function(event) {
if(event.target.value.length > 0) {
this._enableSendButton();
} else {
this._disableSendButton();
}
},

// Quit button pressed, so disconnect; return to main page.
_handleQuit: function() {
ConnectionActions.logout();
return false;
}
});
Loading

0 comments on commit 5299602

Please sign in to comment.