<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>pnChat</title>
<meta name="viewport" content="width=device-width" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" rel="stylesheet" data-semver="3.3.6" data-require="bootstrap-css@3.3.6" />
<link rel="stylesheet" href="main.css" />
<!-- endbuild -->
</head>
<body ng-app="pnChatApp">
<div class="header">
<div class="navbar navbar-default" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#js-navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#/">pnChat</a>
</div>
<div class="collapse navbar-collapse" id="js-navbar-collapse"></div>
</div>
</div>
</div>
<div class="container">
<div ng-view=""></div>
</div>
<div class="footer">
<div class="container">
<p>pnChat Copyright © 2016</p>
</div>
</div>
<!-- Google Analytics: change UA-XXXXX-X to be your site's ID -->
<script>
! function(A, n, g, u, l, a, r) {
A.GoogleAnalyticsObject = l, A[l] = A[l] || function() {
(A[l].q = A[l].q || []).push(arguments)
}, A[l].l = +new Date, a = n.createElement(g),
r = n.getElementsByTagName(g)[0], a.src = u, r.parentNode.insertBefore(a, r)
}(window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga');
ga('create', 'UA-XXXXX-X');
ga('send', 'pageview');
</script>
<script src="https://cdn.pubnub.com/pubnub-3.7.20.js"></script>
<!-- build:js(.) scripts/vendor.js -->
<!-- bower:js -->
<script src="https://code.jquery.com/jquery-2.1.4.js" data-semver="2.1.4" data-require="jquery@*"></script>
<script data-require="angular.js@*" data-semver="1.4.8" src="https://code.angularjs.org/1.4.8/angular.js"></script>
<script src="https://code.angularjs.org/1.4.8/angular-route.js" data-semver="1.4.8" data-require="angular-route@*"></script>
<script src="https://cdn.pubnub.com/sdk/pubnub-angular/pubnub-angular-3.1.0.js"></script>
<!-- endbower -->
<!-- endbuild -->
<!-- build:js({.tmp,app}) scripts/scripts.js -->
<script src="app.js"></script>
<script src="main.js"></script>
<script src="join.js"></script>
<!-- endbuild -->
</body>
</html>
<h4>Welcome {{data.username}}, click to select a channel below [<a href="#/join">Sign Out</a>]</h4>
<ul class="list-unstyled list-inline">
<li class="roomlabel" ng-repeat="channel in channels">
<a class="bt btn-info" href='' ng-class="{'label-default': user != data.username, 'label-default': (channel != selectedChannel), 'label-success':(channel == selectedChannel)}" ng-click='subscribe(channel)'>
<i clas='fa' ng-class="{'fa-spin':(channel == selectedChannel), 'fa-spinner':(channel == selectedChannel), 'fa-comments':(channel != selectedChannel)}"></i>
{{channel}}
</a>
</li>
<li class="roomlabel">
<a class="btn btn-default" href="" ng-click="showCreate = !showCreate">
<i class="fa fa-magic"></i> Create New...
</a>
</li>
<div ng-show="showCreate">
<form ng-submit="createChannel()">
<h6>Create New Room</h6>
<div class="input-group">
<input class="input-sm form-control" ng-model="newChannel" plaseholder="Room Name" type="text">
<span class="input-group-btn">
<input class="input-sm btn btn-default" type="submit" value="Go!">
</span>
</div>
<br>
<br>
</form>
</div>
</ul>
<br>
<div class="row">
<div class="col-md-2">
<small class="marker">Users In Room</small>
<ul class="list-unstyled">
<li ng-repeat="user in users">
<span class='label btn-mini userlabel' ng-class="{'label-default': user != data.username, 'label-success': (user == data.username)}" title='(Location:{{userdata[user].city || "unknown"}})'>
<i class="fa fa-user"></i>
{{user}}
</span>
</li>
</ul>
</div>
<div class="col-md-10">
<form ng-submit="publish()">
<input class="input-sm form-control" ng-model="newMessage" type="text" placeholder="Type a message...">
<span class="input-group-btn">
<input class='input-sm btn btn-default' type="submit" value="Send">
</span>
</form>
<br>
<div class="well chatbox" id="chat_history">
<ul class="list-unstyled">
<li ng-repeat="message in messages">
<i class="fa fa-comment"></i>
{{message}}
</li>
</ul>
</div>
</div>
</div>
<div class="row marketing">
<div class="col-md-12">
<div class="panel panel-default panel-primary" ng-hide="seletedChannel">
<div class="panel-heading">
<h3 class="panel-title">Join Chat</h3>
</div>
<form class="panel-body ng-pristine ng-valid" ng-submit="join()">
<label>
Username
</label>
<input class="input-lg form-control ng-pristine ng-valid" maxlength="20" ng-model="data.username" size="20" type="text"><br>
<label>
City
</label>
<input class="input-lg form-control ng-pristine ng-valid" maxlength="20" ng-model="data.city" size="20" type="text"><br>
<input class="btn btn-block btn-primary" type="submit" value="Join">
</form>
</div>
</div>
</div>
angular
.module('pnChatApp', [
'ngAnimate',
'ngCookies',
'ngResource',
'ngRoute',
'ngSanitize',
'ngTouch',
'pubnub.angular.service'
])
.config(function ($routeProvider) {
$routeProvider
.when('/main', {
templateUrl: 'main.html',
controller: 'MainCtrl'
})
.when('/join', {
templateUrl: 'join.html',
controller: 'JoinCtrl'
})
.otherwise({
redirectTo: '/join'
});
});
angular.module('pnChatApp')
.controller('MainCtrl', ['$scope', '$rootScope', '$location', 'Pubnub', function ($scope, $rootScope, $location, Pubnub) {
var _ref;
if (!Pubnub.init()) {
$location.path('/join');
}
$scope.controlChannel = '__controlchannel';
$scope.channels = [];
//Publish Chat
$scope.publish = function() {
if (!$scope.selectedChannel) {
return;
}
Pubnub.ngPublish({
channel: $scope.selectedChannel,
message: {
text: $scope.newMessage,
user: $scope.data.username
}
});
return $scope.newMessage = '';
};
//Create Channel
$scope.createChannel = function() {
var channel;
console.log('Creating Channel...');
channel = $scope.newChannel;
$scope.newChannel = '';
Pubnub.ngGrant( {
channel: channel,
read: true,
write: true,
callback: function(){
return console.log(channel + 'All Set', arguments);
}
});
Pubnub.ngGrant( {
channel: channel + '-pnpres',
read: true,
write: false,
callback: function(){
return console.log(channel + 'Presence All Set', arguments);
}
});
Pubnub.ngPublish({
channel: $scope.controlChannel,
message: channel
});
return setTimeout(function() {
$scope.subscribe(channel);
return $scope.showCreate = false;
}, 100);
};
$scope.subscribe = function(channel) {
var _ref;
console.log('Subscribing...');
if (channel === $scope.selectedChannel) {
return;
}
if ($scope.selectedChannel) {
Pubnub.ngUnsubscribe({
channel: $scope.selectedChannel
});
}
$scope.selectedChannel = channel;
$scope.messages = ['Welcome to ' + channel];
Pubnub.ngSubscribe({
channel: $scope.selectedChannel,
state: {
"city": ((_ref = $rootScope.data) !== null ? _ref.city : void 0) || 'unknown'
},
error: function() {
return console.log(arguments);
}
});
$rootScope.$on(Pubnub.ngPrsEv($scope.selectedChannel), function(ngEvent, payload) {
return $scope.$apply(function() {
var newData, userData;
userData = Pubnub.ngPresenceData($scope.selectedChannel);
newData = {};
$scope.users = Pubnub.map(Pubnub.ngListPresence($scope.selectedChannel), function(x) {
var newX;
newX = x;
if (x.replace) {
newX = x.replace(/\w+__/, "");
}
if (x.uuid) {
newX = x.uuid.replace(/\w+__/, "");
}
newData[newX] = userData[x] || {};
return newX;
});
return $scope.userData = newData;
});
});
Pubnub.ngHereNow({
channel: $scope.selectedChannel
});
$rootScope.$on(Pubnub.ngMsgEv($scope.selectedChannel), function(ngEvent, payload) {
var msg;
msg = payload.message.user ? "[" + payload.message.user + "]" + payload.message.text : payload.message.text;
return $scope.$apply(function() {
return $scope.messages.unshift(msg);
});
});
return Pubnub.ngHistory({
channel: $scope.selectedChannel,
auth_key: $scope.authKey,
count: 500
});
};
PubNub.ngSubscribe({
channel: $scope.controlChannel
});
$rootScope.$on(PubNub.ngMsgEv($scope.controlChannel), function(ngEvent, payload) {
return $scope.$apply(function() {
if ($scope.channels.indexOf(payload.message) < 0) {
return $scope.channels.push(payload.message);
}
});
});
return PubNub.ngHistory({
channel: $scope.controlChannel,
count: 500
});
$scope.channels = 'TheWaitingRoom';
return $scope.createChannel();
}]);
angular.module('pnChatApp')
.controller('JoinCtrl', ['$scope', '$rootScope', '$location', 'Pubnub', function ($scope,$rootScope,$location, Pubnub) {
$scope.data = {
username: 'User_' + Math.floor(Math.random() * 1000)
};
$scope.join = function() {
console.log('Joining...');
var _ref,_ref1;
$rootScope.data || ($rootScope.data = {});
$rootScope.data.username = (_ref = $scope.data) != null ? _ref.username : void 0;
$rootScope.data.city = (_ref1 = $scope.data) != null ? _ref1.city : void 0;
$rootScope.data.uuid = Math.floor(Math.random() * 1000000) + '__'+ $scope.data.username;
console.log($rootScope);
Pubnub.init({
subscribe_key: 'sub-c-3e4e26ec-c293-11e5-a9aa-02ee2ddab7fe',
publish_key: 'pub-c-55b9afc9-576b-4924-86f4-2a64fb9bf30c',
uuid: $rootScope.data.uuid
});
return $location.path('/main');
};
}]);
.browsehappy {
margin: 0.2em 0;
background: #ccc;
color: #000;
padding: 0.2em 0;
}
body {
padding: 0;
}
/* 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;
margin-bottom: 10px;
}
/* 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;
color: #777;
border-top: 1px solid #e5e5e5;
}
.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) {
.container {
max-width: 730px;
}
/* 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;
}
}