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...