Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 1 addition & 6 deletions .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 3 additions & 4 deletions src/main/java/org/atmosphere/samples/chat/angular/Chat.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public final class Chat{
private static final Logger logger = LoggerFactory.getLogger(Chat.class);

/**
* Invoked when the connection as been fully established and suspended, e.g ready for receiving messages.
* Invoked when the connection has been fully established and suspended, e.g ready for receiving messages.
*
* @param r the atmosphere resource
*/
Expand All @@ -43,8 +43,7 @@ else if(event.isClosedByClient())
}

/**
* Simple annotated class that demonstrate how {@link org.atmosphere.config.managed.Encoder} and {@link org.atmosphere.config.managed.Decoder
* can be used.
* Invoked when a message was received
*
* @param message an instance of {@link ChatMessage }
* @return the chat message
Expand All @@ -56,4 +55,4 @@ public final ChatMessage onMessage(final ChatMessage message) throws IOException
return message;
}

}
}
38 changes: 24 additions & 14 deletions src/main/webapp/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,34 @@
<link rel="stylesheet" href="css/chat.css" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
<script src="javascript/atmosphere.service.js"></script>
<script src="javascript/atmosphere.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script src="//spyboost.github.io/angular-atmosphere/service/angular-atmosphere-service.js"></script>
<script src="javascript/application.js"></script>
<script src="javascript/enter.directive.js"></script>
<script src="javascript/chat.controller.js"></script>
</head>
<body data-ng-app="angular.atmosphere.chat" data-ng-controller="ChatController">
<body data-ng-app="angular.atmosphere.chat" data-ng-controller="ChatController as vm">
<div id="header">
<h3 data-ng-bind="model.header" data-ng-init="model.header='Atmosphere Chat. Default transport is WebSocket, fallback is long-polling'"></h3>
<h3 data-ng-bind="vm.model.header" data-ng-init="vm.model.header='Atmosphere Chat. Default transport is WebSocket, fallback is long-polling'"></h3>
</div>
<p data-ng-show="!model.connected">Connecting...</p>
<p>{{model.content}}</p>
<p data-ng-show="!vm.model.connected">Connecting...</p>
<p>{{vm.model.content}}</p>

<div class="container">
<div class="row">
<div class="row">
<input type="text" data-ng-model="vm.request.url" size="100"/>
<input type="button" data-ng-show="!vm.model.subscribed" data-ng-click="vm.subscribe()" value="subscribe"/>
</div>
<br />

<div class="row">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Chat room</h3>
</div>
<div class="panel-body">
<div class="messages">
<p data-ng-repeat="message in model.messages">
<p data-ng-repeat="message in vm.model.messages">
<span class="time">{{message.date | date:'shortDate'}} {{message.date|date:'shortTime'}}</span>
<span class="author">{{message.author}}</span> :
<span class="text">{{message.text}}</span>
Expand All @@ -36,17 +44,19 @@ <h3 class="panel-title">Chat room</h3>
</div>
</div>
</div>
<span data-ng-show="!model.name">Enter your name:</span>
<div data-ng-show="model.logged">
<span><b>{{model.name}}</b> says:</span>
<span data-ng-show="!vm.model.name">Enter your name:</span>
<div data-ng-show="vm.model.logged">
<span><b>{{vm.model.name}}</b> says:</span>
</div>
<form role="form" class="form-horizontal">
<div class="form-group">
<div class="col-lg-9">
<input type="text" class="form-control" id="input" data-ng-disabled="!model.connected" x-webkit-speech/>
<input type="text" atm-enter="vm.submit()" class="form-control" id="input" data-ng-model="vm.model.message"
data-ng-disabled="!vm.model.connected" x-webkit-speech/>
<input type="submit" style="position: absolute; left: -9999px; width: 1px; height: 1px;"/>
</div>
</div>
</form>
</div>
</body>
</html>
</html>
98 changes: 0 additions & 98 deletions src/main/webapp/javascript/application.js

This file was deleted.

38 changes: 38 additions & 0 deletions src/main/webapp/javascript/atmosphere.service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
angular.module('angular.atmosphere', [])
.service('atmosphereService', function($rootScope){
var responseParameterDelegateFunctions = ['onOpen', 'onClientTimeout', 'onReopen', 'onMessage', 'onClose', 'onError'];
var delegateFunctions = responseParameterDelegateFunctions;
delegateFunctions.push('onTransportFailure');
delegateFunctions.push('onReconnect');

return {
subscribe: function(r){
var result = {};
angular.forEach(r, function(value, property){
if(typeof value === 'function' && delegateFunctions.indexOf(property) >= 0){
if(responseParameterDelegateFunctions.indexOf(property) >= 0)
result[property] = function(response){
$rootScope.$apply(function(){
r[property](response);
});
};
else if(property === 'onTransportFailure')
result.onTransportFailure = function(errorMsg, request){
$rootScope.$apply(function(){
r.onTransportFailure(errorMsg, request);
});
};
else if(property === 'onReconnect')
result.onReconnect = function(request, response){
$rootScope.$apply(function(){
r.onReconnect(request, response);
});
};
}else
result[property] = r[property];
});

return atmosphere.subscribe(result);
}
};
});
112 changes: 112 additions & 0 deletions src/main/webapp/javascript/chat.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
angular.module('angular.atmosphere.chat', ['angular.atmosphere']).controller('ChatController', ChatController);

function ChatController($scope, atmosphereService){
var vm = this;
var socket;

vm.model = {
transport: 'websocket',
messages: [],
subscribed: false,
message: null,
};

vm.submit = handleSubmit;
vm.subscribe = handleSubscription;

vm.request = {
url: 'http://rumpel:7777/atmosphere-chat-angular-1.0.0-SNAPSHOT/chat',
contentType: 'application/json',
logLevel: 'debug',
transport: 'websocket',
trackMessageLength: true,
reconnectInterval: 5000,
enableXDR: true,
timeout: 60000,
onOpen: onRequestOpen,
onClientTimeout: onRequestClientTimeout,
onReopen: onRequestReopen,
onTransportFailure: onRequestTransportFailure,
onMessage: onRequestMessage,
onClose: onRequestClose,
onError: onRequestError,
onReconnect: onRequestReconnect
};

//////////////////////////////////////////////////////////////////

function onRequestOpen(response) {
vm.model.transport = response.transport;
vm.model.connected = true;
vm.model.content = 'Atmosphere connected using ' + response.transport;
};

function onRequestClientTimeout(response){
vm.model.content = 'Client closed the connection after a timeout. Reconnecting in ' + vm.request.reconnectInterval;
vm.model.connected = false;
socket.push(atmosphere.util.stringifyJSON({ author: vm.model.name || '', message: 'is inactive and closed the'
+ 'connection. Will reconnect in ' + vm.request.reconnectInterval }));
setTimeout(function(){
socket = atmosphereService.subscribe(vm.request);
}, vm.request.reconnectInterval);
};

function onRequestReopen(response){
vm.model.connected = true;
vm.model.content = 'Atmosphere re-connected using ' + response.transport;
};

function onRequestTransportFailure(errorMsg, request){
atmosphere.util.info(errorMsg);
vm.request.fallbackTransport = 'long-polling';
vm.model.header = 'Atmosphere Chat. Default transport is WebSocket, fallback is ' + vm.request.fallbackTransport;
};

function onRequestMessage(response){
var responseText = response.responseBody;
try{
var message = atmosphere.util.parseJSON(responseText);
if(!vm.model.logged && vm.model.name)
vm.model.logged = true;
else{
var date = typeof(message.time) === 'string' ? parseInt(message.time) : message.time;
vm.model.messages.push({author: message.author, date: new Date(date), text: message.message});
}
}catch(e){
console.error("Error parsing JSON: ", responseText);
throw e;
}
};

function onRequestClose(response){
vm.model.connected = false;
vm.model.content = 'Server closed the connection after a timeout';
socket.push(atmosphere.util.stringifyJSON({ author: vm.model.name, message: 'disconnecting' }));
};

function onRequestError(response){
vm.model.content = "Sorry, but there's some problem with your socket or the server is down";
vm.model.logged = false;
};

function onRequestReconnect(request, response){
vm.model.content = 'Connection lost. Trying to reconnect ' + vm.request.reconnectInterval;
vm.model.connected = false;
};

function handleSubscription () {
socket = atmosphereService.subscribe(vm.request);
vm.model.subscribed = true;
}

function handleSubmit () {
if (vm.model.message) {
if (!vm.model.name) {
vm.model.name = vm.model.message;
}

socket.push(atmosphere.util.stringifyJSON( {author: vm.model.name, message: vm.model.message} ));
vm.model.message='';
}
}
}
12 changes: 12 additions & 0 deletions src/main/webapp/javascript/enter.directive.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
angular.module('angular.atmosphere').directive('atmEnter', function() {
return function(scope, element, attrs) {
element.bind("keydown keypress", function(event) {
if(event.which === 13) {
scope.$apply(function(){
scope.$eval(attrs.atmEnter, {'event': event});
});
event.preventDefault();
}
});
};
});