JSFiddle - React, Tailwind, and code Playground
by Sean Wessell
HTML
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script>
<script src="//cdn.firebase.com/libs/angularfire/0.9.0/angularfire.min.js"></script>
<script src="//cdn.firebase.com/js/client/2.0.3/firebase.js"></script>
<div class="container">
<div ng-app="commentApp" ng-controller="ChatCtrl">
<div class="chatbox">
<div class="well" ng-show="messages.length == 0">Be the 1st to add a comment...</div>
<div class="row" ng-repeat="message in messages | reverse">
<div class="col-md-1 col-md-offset-3">
<!-- /thumbnail -->
</div>
<!-- /col-sm-1 -->
<div class="col-md-5">
<div class="panel comment panel-default">
<div class="panel-heading">
<strong>{{message.from}}</strong> <span class="text-muted">commented {{timeSince(message.postdate)}} ago</span>
</div>
<div class="panel-body">
<div class="col-xs-2">
<img class="img-responsive user-photo" src="https://ssl.gstatic.com/accounts/ui/avatar_2x.png">
</div>
<div class="col-xs-10">{{message.content}}</div>
<!-- /panel-body -->
</div>
<!-- /panel panel-default -->
</div>
<!-- /col-sm-5 -->
</div>
<!-- /row -->
</div>
<form ng-submit="addMessage()">
<div class="input-group">
<input id="btn-input" type="text" class="form-control input-sm" placeholder="enter comment here..." ng-model="message" /> <span class="input-group-btn">
<button class="btn btn-primary btn-sm" type="submit">Send</button>
</span>
</div>
...
CSS
.panel.comment {
position:relative;
}
.panel.comment>.panel-heading:after, .panel.comment>.panel-heading:before {
position:absolute;
top:11px;
left:-16px;
right:100%;
width:0;
height:0;
display:block;
content:" ";
border-color:transparent;
border-style:solid solid outset;
pointer-events:none;
}
.panel.comment>.panel-heading:after {
border-width:7px;
border-right-color:#f7f7f7;
margin-top:1px;
margin-left:2px;
}
.panel.comment>.panel-heading:before {
border-right-color:#ddd;
border-width:8px;
}
.user-photo {
margin: 0px 0px 0px 0px;
min-height:30px;
min-width: 30px;
max-height:80px;
}
JavaScript
var app = angular.module("commentApp", ["firebase"]);
app.factory("chatMessages", ["$firebase", '$rootScope',
function ($firebase, $rootScope) {
var ref = new Firebase("https://blogsjw.firebaseio.com/comments");
return $firebase(ref).$asArray();
}]);
app.filter('reverse', function () {
function toArray(list) {
var k, out = [];
if (list) {
if (angular.isArray(list)) {
out = list;
} else if (typeof (list) === 'object') {
for (k in list) {
if (list.hasOwnProperty(k)) {
out.push(list[k]);
}
}
}
}
return out;
}
return function (items) {
return toArray(items).slice().reverse();
};
});
app.controller("ChatCtrl", ["$scope", "chatMessages",
function ($scope, chatMessages) {
$scope.timeSince = function (date) {
var seconds = Math.floor((new Date() - new Date(date)) / 1000);
var interval = Math.floor(seconds / 31536000);
if (interval > 1) {
return interval + " years";
}
interval = Math.floor(seconds / 2592000);
if (interval > 1) {
return interval + " months";
}
interval = Math.floor(seconds / 86400);
if (interval > 1) {
return interval + " days";
}
interval = Math.floor(seconds / 3600);
if (interval > 1) {
return interval + " hours";
}
interval = Math.floor(seconds / 60);
if (interval >= 1) {
return interval + " minutes";
}
return Math.floor(seconds) + " seconds";
}
$scope.user = "Guest";
$scope.message = "";
$scope.messages = chatMessages;
$scope.addMessage = function () {
$scope.messages.$add({
from: $scope.user,
content: $scope.message,
postdate: "" + new Date()
});
$scope.message...