/* * Spreed WebRTC. * Copyright (C) 2013-2014 struktur AG * * This file is part of Spreed WebRTC. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . * */ define(['jquery', 'underscore', 'moment', 'text!partials/fileinfo.html', 'text!partials/contactrequest.html', 'text!partials/geolocation.html'], function($, _, moment, templateFileInfo, templateContactRequest, templateGeolocation) { // ChatroomController return ["$scope", "$element", "$window", "safeMessage", "safeDisplayName", "$compile", "$filter", "translation", function($scope, $element, $window, safeMessage, safeDisplayName, $compile, $filter, translation) { $scope.outputElement = $element.find(".output"); $scope.inputElement = $element.find(".input"); $scope.bodyElement = $element.find(".chatbody"); $scope.menuElement = $element.find(".chatmenu"); var lastSender = null; var lastDate = null; var lastMessageContainer = null; var senderExpired = null; var isTyping = false; var isTypingExpired = null; var peerTypingExpired = null; var p2p = false; var scrollAfterInput = false; // Mark seen on several events. $scope.bodyElement.on("mouseover mouseenter touchstart", _.debounce(function(event) { $scope.$parent.seen(); $scope.$apply(); }, 100)); var displayName = safeDisplayName; var buddyImageSrc = $filter("buddyImageSrc"); var fileInfo = $compile(templateFileInfo); var contactRequest = $compile(templateContactRequest); var geoLocation = $compile(templateGeolocation); var knowMessage = { r: {}, pending: [], register: function(element, mid, status, received) { if (mid) { if (knowMessage.r.hasOwnProperty(mid)) { console.warn("Duplicate chat message registration.", mid, element, status); return; } var e = knowMessage.r[mid] = { element: element, status: status } if (e.status) { element.addClass(e.status); } if (received) { knowMessage.pending.push(mid); $scope.$emit("submitreceived", mid); } } }, update: function(mid, status) { var e = knowMessage.r[mid]; if (e) { if (e.status !== status && status) { if (e.status) { e.element.removeClass(e.status); } e.status = status; e.element.addClass(e.status); if (status === "received" || status === "read") { // last one - cleanup delete knowMessage.r[mid]; } } } }, seen: function() { var pending = knowMessage.pending; if (pending.length) { knowMessage.pending = []; $scope.$emit("submitseen", pending); _.each(pending, function(mid) { knowMessage.update(mid, "read"); }); } } }; // Make sure that chat links are openend in a new window. $element.on("click", function(event) { var elem = $(event.target); if (elem.is("a")) { var url = elem.attr("href"); if (url && !elem.attr("download")) { if (url.match(/mailto:/gi) === null) { event.preventDefault(); $window.open(elem.attr("href"), "_blank"); } } } }); $scope.$watch("input", function(newvalue) { $scope.$parent.seen(); $window.clearTimeout(isTypingExpired); if (!newvalue) { return; } if (!isTyping) { isTyping = true; $scope.$emit("typing", { who: "local", status: "start" }); } isTypingExpired = $window.setTimeout(function() { isTyping = false; $scope.$emit("typing", { who: "local", status: "stop" }); }, 4000); }); $scope.reset = function() { $scope.input = ""; isTyping = false; $window.clearTimeout(isTypingExpired); }; $scope.focus = function() { $scope.inputElement.focus(); }; $scope.submit = function() { var input = $scope.input; if (input) { scrollAfterInput = true; $scope.$emit("submit", $scope.input); $scope.reset(); $scope.focus(); } }; $scope.canScroll = function() { var o = $scope.outputElement[0]; if ((o.clientHeight - 20) < o.scrollHeight) { if (!scrollAfterInput && (o.clientHeight + 20) < (o.scrollHeight - o.scrollTop)) { // Manually scrolled -> do nothing. } else { scrollAfterInput = false; // Return scroll function. return function() { o.scrollTop = o.scrollHeight; }; } } return false; } $scope.display = function(s, nodes, extra_css, title, picture) { var container; var element; var scroll = this.canScroll(); lastMessageContainer = null; if (!extra_css) { extra_css = ""; } if (s || title || picture) { container = $('
'); if (title) { container.prepend(title); } if (picture) { container.prepend(picture); } lastMessageContainer = $("