Source: directives/telegram/telegram-chat/2.telegram-chat.js

    /**
     * @ngdoc directives
     * @name TelegramChat
     * @module s4c.directives.TelegramChat.TelegramChat
     *
     * @description
     * `TelegramChat` Dashboard do telegram
     *
     * @example
     *   <s4c-telegram-chat>
     *   </s4c-telegram-chat>
     */

(function () {
    'use strict';

    s4cTelegramChat.$inject = [
        'TelegramService',
        'CommService',
        '$timeout',
        '$q',
        '$interval',
        'localize'
    ];

    function s4cTelegramChat(TelegramService, CommService, $timeout, $q, $interval, localize) {
        return {
            restrict: 'E',
            templateUrl: 'app/directives/telegram/telegram-chat/telegram-chat.html',
            //controller: telegramChatCtrl,
            scope: {
                'ativo': '=ativo',
                'group': '=group'
            },
            link: function ($scope, $elem, $attrs) {
                $scope.selectedSearch = {
                    originalMessage: '',
                    message: '',
                    id: null
                };

                /**
                 * @method restoreFindText
                 */
                $scope.restoreFindText = function () {
                    if ($scope.selectedSearch.id !== null) {
                        var messageLast = _.find($scope.selectedGroup.messages, { id: $scope.selectedSearch.id });
                        if (messageLast) {
                            messageLast.texto = $scope.selectedSearch.originalMessage;
                        }
                    }
                };

                /**
                 * @method findNextMatch
                 */
                $scope.findNextMatch = function () {

                    $scope.nextMessageIndex++;

                    if (!$scope.searchResults[$scope.nextMessageIndex]) {
                        $scope.nextMessageIndex = 0;
                    }

                    $scope.restoreFindText();

                    var messageGroup = _.find($scope.selectedGroup.messages, { id: $scope.searchResults[$scope.nextMessageIndex].id });
                    if (!messageGroup) {
                        if ($scope.nextMessageIndex >= ($scope.searchResults.length - 1)) {
                            $scope.nextMessageIndex = -1;
                        }
                        return $scope.findNextMatch();
                    }
                    $scope.selectedSearch.originalMessage = angular.copy(messageGroup.texto);
                    $scope.selectedSearch.id = messageGroup.id;
                    var messageStr = $scope.searchResults[$scope.nextMessageIndex].texto;
                    messageGroup.texto = angular.copy(messageStr);

                    $elem
                        .find('.mensagem-list')
                        .scrollTo($elem.find('#' + $scope.searchResults[$scope.nextMessageIndex].id));
                };

                /**
                 * @method findPreviousMatch
                 */
                $scope.findPreviousMatch = function () {
                    $scope.nextMessageIndex--;

                    if (!$scope.searchResults[$scope.nextMessageIndex]) {
                        $scope.nextMessageIndex = $scope.searchResults.length - 1;
                    }

                    $scope.restoreFindText();

                    var messageGroup = _.find($scope.selectedGroup.messages, { id: $scope.searchResults[$scope.nextMessageIndex].id });
                    if (!messageGroup) {
                        if ($scope.nextMessageIndex <= 0) {
                            $scope.nextMessageIndex = $scope.searchResults.length;
                        }
                        return $scope.findPreviousMatch();
                    }
                    $scope.selectedSearch.originalMessage = angular.copy(messageGroup.texto);
                    $scope.selectedSearch.id = messageGroup.id;
                    var messageStr = $scope.searchResults[$scope.nextMessageIndex].texto;
                    messageGroup.texto = angular.copy(messageStr);

                    $elem
                        .find('.mensagem-list')
                        .scrollTo($elem.find('#' + $scope.searchResults[$scope.nextMessageIndex].id));
                }
            },
            controller: ['$scope', '$q', '$timeout', 'TelegramService', 'CommService', 'localize', function ($scope, $q, $timeout, TelegramService, CommService, localize) {

                $scope.page = 0;
                $scope.ativo = false;
                $scope.form = {
                    message: ''
                };
                $scope.filters = {
                    message: ''
                };

                $scope.res = $scope.$root.res;

                var index;
                var indexedMessages = {};

                /**
                 * @method addMarkers
                 */
                function addMarkers() {
                    _.remove($scope.selectedGroup.messages, function (message) {
                        return message.dateLimiter;
                    });

                    _.reduce($scope.selectedGroup.messages, function (x, y, index) {
                        var date1 = moment(x.data);
                        var date2 = moment(y.data);
                        var today = moment();
                        var texto = '';

                        if (date2.diff(today, 'days') === 0) {
                            texto = 'HOJE';
                        } else if (date2.diff(today, 'days') === -1) {
                            texto = 'ONTEM';
                        } else {
                            texto = date2.format('DD/MM/YYYY');
                        }

                        if (date1.format('D') < date2.format('D')) {
                            var x = {
                                texto: texto,
                                dateLimiter: true
                            };
                            $scope.selectedGroup.messages.splice(index, 0, x);
                        }

                        return y;
                    }, $scope.selectedGroup.messages[0]);
                }

                /**
                 * @method enviarMensagem
                 */
                $scope.enviarMensagem = function () {
                    if ($scope.form.message.length <= 0) return;

                    TelegramService.enviarMensagem($scope.selectedGroup.id, $scope.form).then(function () {
                        $scope.form.message = '';
                    });
                };

                /**
                 * @method loadMoreMessages
                 */
                $scope.loadMoreMessages = function () {
                    $scope.page++;

                    return TelegramService.getGroupMessages($scope.selectedGroup.id, $scope.page)
                        .then(function (messages) {
                            if (messages.length <= 0 && $scope.page > 0) $scope.page--;

                            $scope.selectedGroup.messages = _.chain($scope.selectedGroup.messages.concat(messages))
                                .map(function (m) {
                                    if (m.texto) {
                                        m.texto = m.texto.trim();
                                    }
                                    return m;
                                })
                                .uniqBy('id')
                                .orderBy('id')
                                .value();

                            addMarkers();
                        });
                };

                /**
                 * @method search
                 */
                $scope.search = function () {
                    TelegramService.findGroupMessagePages($scope.selectedGroup.id, $scope.filters.message)
                        .then(function (pageNumbers) {
                            if (pageNumbers.length) {
                                _reloadMessages(0, _.max(pageNumbers).page).then(function () {

                                    $scope.searchResults = _.chain(pageNumbers).flatMap(function (t) { return t.messages; })
                                        .orderBy(['id'], ['asc']).value();

                                    if ($scope.searchResults.length) {
                                        $scope.nextMessageIndex = -1;
                                        $scope.findNextMatch();
                                    }
                                });
                            }
                        });
                };

                /**
                 * @method clearSearch
                 */
                $scope.clearSearch = function () {
                    $scope.searchResults = [];
                    $scope.filters.message = '';
                    $scope.restoreFindText();
                };

                /**
                 * @method _scrollMessages
                 */
                function _scrollMessages() {
                    $timeout(function () {
                        var messages = $('.mensagem-list');
                        messages = messages.slice();
                        _.each(messages, function (message) {
                            message.scrollTop = message.scrollHeight;
                        });
                    }, 1000);
                }

                /**
                 * @method _reloadMessages 
                 * 
                 * @param {*} pageNumber 
                 * @param {*} pageToNumber 
                 */
                function _reloadMessages(pageNumber, pageToNumber) {

                    return TelegramService.getGroupMessages($scope.selectedGroup.id, pageNumber, pageToNumber)
                        .then(function (messages) {

                            $scope.selectedGroup.messages = _.chain(messages)
                                .uniqBy('id')
                                .orderBy('id')
                                .each(function (message) {
                                    if (message.texto) {
                                        message.texto = message.texto.trim();
                                    }
                                })
                                .value();

                            _scrollMessages();
                            addMarkers();
                        })

                }

                /**
                 * @method $watch_group.selectedGroup
                 */
                $scope.$watch('group.selectedGroup', function () {
                    if (!$scope.group.selectedGroup) return;

                    $scope.selectedGroup = $scope.group.selectedGroup;

                    $timeout(function () {
                        _reloadMessages(0, 0);
                    });
                }, false);

                $scope.count_new_messages = 0;
                $scope.isOutScroll = false;

                document.getElementById('mensagem-list-telegram').onscroll = function () {
                    var objScroll = document.getElementById('mensagem-list-telegram');
                    var h = objScroll.offsetHeight;
                    var limit = objScroll.scrollHeight - h;

                    if (objScroll.scrollTop < (limit - h)) {
                        $scope.isOutScroll = true;
                        return;
                    }
                    $scope.isOutScroll = false;
                    $scope.count_new_messages = 0;
                };

                /**
                 * @method scrollToBottom
                 */
                $scope.scrollToBottom = function () {
                    var objScroll = document.getElementById('mensagem-list-telegram');
                    var h = objScroll.offsetHeight;
                    var limit = objScroll.scrollHeight - h;

                    objScroll.scrollTop = limit;
                    $scope.count_new_messages = 0;
                };

                /**
                 * @method changeMessage
                 */
                $scope.changeMessage = function (countMessage) {
                    if ($scope.isOutScroll) {
                        $scope.count_new_messages += countMessage;
                        return;
                    }

                    $scope.scrollToBottom();
                };

                /**
                 * @method CommService_mensageria_externa_mensagem
                 */
                CommService.on('mensageria_externa:mensagem', function (message) {
                    if ($scope.selectedGroup.id === message.GrupoMensageriaExternaId) {
                        $scope.selectedGroup.messages.push(message);
                        //index.add(message);
                        indexedMessages[message.id] = message;
                        $timeout(function () {
                            $scope.changeMessage(1);
                            //_scrollMessages();
                        }, 500);
                    }
                });
            }]
        };
    }

    angular.module('s4c.components.telegram')
        .directive('s4cTelegramChat', s4cTelegramChat);
}());