You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
682 lines
27 KiB
682 lines
27 KiB
<?php |
|
|
|
/** |
|
* secure_chat.php |
|
* |
|
* @package OpenEMR |
|
* @link https://www.open-emr.org |
|
* @author Jerry Padgett <sjpadgett@gmail.com> |
|
* @author Brady Miller <brady.g.miller@gmail.com> |
|
* @author Tyler Wrenn <tyler@tylerwrenn.com> |
|
* @copyright Copyright (c) 2016-2021 Jerry Padgett <sjpadgett@gmail.com> |
|
* @copyright Copyright (c) 2019 Brady Miller <brady.g.miller@gmail.com> |
|
* @copyright Copyright (c) 2022 Tyler Wrenn <tyler@tylerwrenn.com> |
|
* @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3 |
|
*/ |
|
|
|
namespace PatientPortal; |
|
|
|
// Will start the (patient) portal OpenEMR session/cookie. |
|
require_once(__DIR__ . "/../../src/Common/Session/SessionUtil.php"); |
|
\OpenEMR\Common\Session\SessionUtil::portalSessionStart(); |
|
|
|
if (isset($_SESSION['pid']) && isset($_SESSION['patient_portal_onsite_two'])) { |
|
$pid = $_SESSION['pid']; |
|
$ignoreAuth_onsite_portal = true; |
|
require_once(__DIR__ . "/../../interface/globals.php"); |
|
define('IS_DASHBOARD', false); |
|
define('IS_PORTAL', $_SESSION['pid']); |
|
} else { |
|
\OpenEMR\Common\Session\SessionUtil::portalSessionCookieDestroy(); |
|
$ignoreAuth = false; |
|
require_once(__DIR__ . "/../../interface/globals.php"); |
|
if (!isset($_SESSION['authUserID'])) { |
|
$landingpage = "index.php"; |
|
header('Location: ' . $landingpage); |
|
exit; |
|
} |
|
$admin = sqlQueryNoLog( |
|
"SELECT CONCAT(users.fname,' ',users.lname) as user_name FROM users WHERE id = ?", |
|
array($_SESSION['authUserID']) |
|
); |
|
define('ADMIN_USERNAME', $admin['user_name']); |
|
define('IS_DASHBOARD', $_SESSION['authUser']); |
|
define('IS_PORTAL', false); |
|
$_SERVER['REMOTE_ADDR'] = 'admin::' . $_SERVER['REMOTE_ADDR']; |
|
} |
|
|
|
// Ensure that username GET or POST parameters are not manipulated |
|
$usernameManipulatedFlag = false; |
|
if (!empty($_GET['username']) && ($_GET['username'] != 'currentol')) { |
|
if (empty(IS_PORTAL)) { |
|
if ($_GET['username'] != ADMIN_USERNAME) { |
|
$usernameManipulatedFlag = true; |
|
} |
|
} else { |
|
if ($_GET['username'] != $_SESSION['ptName']) { |
|
$usernameManipulatedFlag = true; |
|
} |
|
} |
|
} |
|
if (!empty($_POST['username'])) { |
|
if (empty(IS_PORTAL)) { |
|
if ($_POST['username'] != ADMIN_USERNAME) { |
|
$usernameManipulatedFlag = true; |
|
} |
|
} else { |
|
if ($_POST['username'] != $_SESSION['ptName']) { |
|
$usernameManipulatedFlag = true; |
|
} |
|
} |
|
} |
|
if ($usernameManipulatedFlag) { |
|
http_response_code(401); |
|
die(xlt("Something went wrong")); |
|
} |
|
|
|
use OpenEMR\Core\Header; |
|
use OpenEMR\PatientPortal\Chat\ChatController; |
|
|
|
define('C_USER', IS_PORTAL ?: IS_DASHBOARD); |
|
define('CHAT_HISTORY', '150'); |
|
define('CHAT_ONLINE_RANGE', '1'); |
|
define('ADMIN_USERNAME_PREFIX', 'adm_'); |
|
|
|
// Start application. |
|
$msgApp = new ChatController(); |
|
?> |
|
<!doctype html> |
|
<html ng-app="MsgApp"> |
|
<head> |
|
<meta charset="utf-8" /> |
|
<?php |
|
Header::setupHeader(['no_main-theme', 'ckeditor', 'angular', 'angular-sanitize', 'checklist-model']); |
|
?> |
|
<title><?php echo xlt('Secure Chat'); ?></title> |
|
<meta name="author" content="Jerry Padgett sjpadgett{{at}} gmail {{dot}} com" /> |
|
</head> |
|
<script> |
|
(function () { |
|
var MsgApp = angular.module('MsgApp', ['ngSanitize', "checklist-model"]); |
|
MsgApp.config(function ($compileProvider) { |
|
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|file|ftp|blob):|data:image\//); |
|
} |
|
); |
|
MsgApp.directive('ngEnter', function () { |
|
return function (scope, element, attrs) { |
|
element.bind("keydown keypress", function (event) { |
|
if (event.which === 13) { |
|
scope.$apply(function () { |
|
scope.$eval(attrs.ngEnter); |
|
}); |
|
event.preventDefault(); |
|
} |
|
}); |
|
}; |
|
}); |
|
MsgApp.directive('tooltip', function (e) { |
|
return { |
|
restrict: 'A', |
|
link: function (scope, element, attrs) { |
|
$(element).hover(function () { |
|
$(element).tooltip('show'); |
|
}, function () { |
|
$(element).tooltip('hide'); |
|
}); |
|
} |
|
}; |
|
}); |
|
MsgApp.filter('unique', function () { |
|
return function (collection, keyname) { |
|
var output = [], |
|
keys = []; |
|
angular.forEach(collection, function (item) { |
|
var key = item[keyname]; |
|
if (keys.indexOf(key) === -1) { |
|
keys.push(key); |
|
output.push(item); |
|
} |
|
}); |
|
return output; |
|
}; |
|
}); |
|
|
|
MsgApp.controller('MsgAppCtrl', ['$scope', '$http', '$filter', function ($scope, $http, $filter) { |
|
$scope.urlListMessages = '?action=list'; // actions for restful |
|
$scope.urlSaveMessage = '?action=save'; |
|
$scope.urlListOnlines = '?action=ping'; |
|
$scope.urlGetAuthUsers = '?action=authusers'; |
|
|
|
$scope.pidMessages = null; |
|
$scope.pidPingServer = null; |
|
|
|
$scope.beep = new Audio('beep.ogg'); // you've got mail!!!! really just a beep |
|
$scope.messages = []; |
|
$scope.online = null; |
|
$scope.lastMessageId = null; |
|
$scope.historyFromId = null; |
|
$scope.onlines = []; // all online users id and ip's |
|
$scope.user = <?php echo $_SESSION['ptName'] ? js_escape($_SESSION['ptName']) : js_escape(ADMIN_USERNAME); ?>;// current user - dashboard user is from session authUserID |
|
$scope.userid = <?php echo IS_PORTAL ? js_escape($_SESSION['pid']) : js_escape($_SESSION['authUser']); ?>; |
|
$scope.isPortal = "<?php echo IS_PORTAL;?>"; |
|
$scope.pusers = []; // selected recipients for chat |
|
$scope.chatusers = []; // authorize chat recipients for dashboard user |
|
$scope.noRecipError = <?php echo xlj("Please Select a Recipient for Message.") ?>; |
|
$scope.me = { |
|
username: $scope.user, |
|
message: null, |
|
sender_id: $scope.userid, |
|
recip_id: 0 |
|
}; |
|
$scope.checkAll = function () { |
|
$scope.pusers = []; |
|
$scope.pusers = $scope.chatusers.map(function (item) { |
|
return item.recip_id; |
|
}); |
|
$scope.getAuthUsers(); |
|
}; |
|
$scope.uncheckAll = function () { |
|
$scope.pusers = []; |
|
$scope.getAuthUsers(); |
|
}; |
|
$scope.makeCurrent = function (sel) { |
|
if (!sel.me) { |
|
$scope.pusers.splice(0, $scope.pusers.length); |
|
$scope.pusers.push(sel.sender_id); |
|
} |
|
}; |
|
$scope.pageTitleNotificator = { |
|
vars: { |
|
originalTitle: window.document.title, |
|
interval: null, |
|
status: 0 |
|
}, |
|
on: function (title, intervalSpeed) { |
|
var self = this; |
|
if (!self.vars.status) { |
|
self.vars.interval = window.setInterval(function () { |
|
window.document.title = (self.vars.originalTitle === window.document.title) ? |
|
title : self.vars.originalTitle; |
|
}, intervalSpeed || 500); |
|
self.vars.status = 1; |
|
} |
|
}, |
|
off: function () { |
|
window.clearInterval(this.vars.interval); |
|
window.document.title = this.vars.originalTitle; |
|
this.vars.status = 0; |
|
} |
|
}; |
|
|
|
$scope.editor = ''; |
|
$scope.editmsg = function () { |
|
$scope.editor = CKEDITOR.instances['messageContent']; |
|
if ($scope.editor) { |
|
$scope.editor.destroy(true); |
|
} |
|
$scope.editor = CKEDITOR.replace('messageContent', { |
|
toolbarGroups: [ |
|
{ name: 'document', groups: [ 'mode', 'document', 'doctools' ] }, |
|
{ name: 'clipboard', groups: [ 'clipboard', 'undo' ] }, |
|
{ name: 'editing', groups: [ 'find', 'selection', 'spellchecker', 'editing' ] }, |
|
{ name: 'forms', groups: [ 'forms' ] }, |
|
{ name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] }, |
|
{ name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi', 'paragraph' ] }, |
|
{ name: 'links', groups: [ 'links' ] }, |
|
{ name: 'insert', groups: [ 'insert' ] }, |
|
{ name: 'styles', groups: [ 'styles' ] }, |
|
{ name: 'colors', groups: [ 'colors' ] }, |
|
{ name: 'tools', groups: [ 'tools' ] }, |
|
{ name: 'others', groups: [ 'others' ] }, |
|
{ name: 'about', groups: [ 'about' ] } |
|
], |
|
removeButtons: 'About,Table,Smiley,SpecialChar,PageBreak,Iframe,HorizontalRule,Anchor,Unlink,Link,NumberedList,BulletedList,Outdent,Indent,Blockquote,CreateDiv,JustifyLeft,JustifyCenter,JustifyRight,JustifyBlock,Language,BidiRtl,BidiLtr,CopyFormatting,RemoveFormat,Superscript,Subscript,Strike,Underline,Italic,Bold,Form,Checkbox,Radio,TextField,Textarea,Select,Button,ImageButton,HiddenField,SelectAll,Scayt,Find,Replace,PasteFromWord,Templates,NewPage,ExportPdf,Maximize,ShowBlocks,Source,Save,Preview,Print,Cut,Copy,Paste,PasteText,TextColor,BGColor', |
|
height: 250, |
|
width: '100%', |
|
resize_maxHeight: 650 |
|
}); |
|
}; |
|
|
|
$scope.saveedit = function () { |
|
$scope.me.message = CKEDITOR.instances.messageContent.getData(); |
|
$scope.saveMessage(); |
|
$scope.editor.destroy(true); |
|
}; |
|
|
|
$scope.saveMessage = function (form, callback) { |
|
$scope.me.recip_id = JSON.stringify(angular.copy($scope.pusers)); |
|
var data = $.param($scope.me); |
|
if (!($scope.me.username && $scope.me.username.trim())) { |
|
return $scope.openModal(); |
|
} |
|
if (!($scope.me.message && $scope.me.message.trim() && |
|
$scope.me.username && $scope.me.username.trim())) { |
|
return; |
|
} |
|
if ($scope.me.recip_id == "[]") { |
|
alert($scope.noRecipError); |
|
return; |
|
} |
|
$scope.me.message = ''; |
|
return $http({ |
|
method: 'POST', |
|
url: $scope.urlSaveMessage, |
|
data: data, |
|
headers: {'Content-Type': 'application/x-www-form-urlencoded'} |
|
}).then(function successCallback(response) { |
|
$scope.listMessages(true); |
|
}, function errorCallback(response) { |
|
}); |
|
}; |
|
|
|
$scope.replaceShortcodes = function (message) { |
|
var msg = ''; |
|
msg = message.toString().replace(/(\[img])(.*)(\[\/img])/, "<img class='img-responsive' src='$2' />"); |
|
msg = msg.toString().replace(/(\[url])(.*)(\[\/url])/, "<a href='$2'>$2</a>"); |
|
msg = message.toString().replace("<img ", "<img class='img-responsive' "); |
|
return msg; |
|
}; |
|
|
|
$scope.notifyLastMessage = function () { |
|
if (typeof window.Notification === 'undefined') { |
|
return; |
|
} |
|
window.Notification.requestPermission(function (permission) { |
|
var lastMessage = $scope.getLastMessage(); |
|
if (permission === 'granted' && lastMessage && lastMessage.username) { |
|
var notify = new window.Notification('Message notification from ' + lastMessage.username + ' : ', { |
|
body: 'New message' //lastMessage.message |
|
}); |
|
notify.onclick = function () { |
|
window.focus(); |
|
}; |
|
notify.onclose = function () { |
|
$scope.pageTitleNotificator.off(); |
|
}; |
|
let timer = setInterval(function () { |
|
notify && notify.close(); |
|
typeof timer !== 'undefined' && window.clearInterval(timer); |
|
}, 100000); |
|
} |
|
}); |
|
}; |
|
|
|
$scope.getLastMessage = function () { |
|
return $scope.messages[$scope.messages.length - 1]; |
|
}; |
|
|
|
$scope.listMessages = function (wasListingForMySubmission) { |
|
return $http.post($scope.urlListMessages, {}).then(function successCallback(response) { |
|
$scope.messages = []; |
|
angular.forEach(response.data, function (message) { |
|
message.message = $scope.replaceShortcodes(message.message); |
|
$scope.messages.push(message); |
|
}); |
|
|
|
var lastMessage = $scope.getLastMessage(); |
|
var lastMessageId = lastMessage && lastMessage.id; |
|
|
|
if ($scope.lastMessageId !== lastMessageId) { |
|
$scope.onNewMessage(wasListingForMySubmission); |
|
} |
|
$scope.lastMessageId = lastMessageId; |
|
if ($scope.pusers === '') { // refresh current in chat list. |
|
angular.forEach($filter('unique')($scope.messages, 'sender_id'), function (m, k) { |
|
var flg = false; |
|
angular.forEach($scope.pusers, function (id) { |
|
if (id === m.sender_id) { |
|
flg = true; |
|
} |
|
}); |
|
if (!flg) $scope.pusers.push(m.sender_id); |
|
}); |
|
} |
|
$scope.getOnlines(); |
|
}, function errorCallback(response) { |
|
}); |
|
}; |
|
|
|
$scope.onNewMessage = function (wasListingForMySubmission) { |
|
if ($scope.lastMessageId && !wasListingForMySubmission) { |
|
$scope.playAudio(); |
|
$scope.pageTitleNotificator.on('New message'); |
|
$scope.notifyLastMessage(); |
|
} |
|
$scope.scrollDown(); |
|
window.addEventListener('focus', function () { |
|
$scope.pageTitleNotificator.off(); |
|
}); |
|
}; |
|
|
|
$scope.getAuthUsers = function () { |
|
$scope.chatusers = []; |
|
return $http.post($scope.urlGetAuthUsers, {}).then(function successCallback(response) { |
|
$scope.chatusers = response.data; |
|
}, function errorCallback(response) { |
|
}); |
|
}; |
|
|
|
$scope.pingServer = function (msgItem) { |
|
return $http.post($scope.urlListOnlines + '&username=' + $scope.user, {}).then(function successCallback(response) { |
|
$scope.online = response.data; |
|
}, function errorCallback(response) { |
|
}); |
|
}; |
|
|
|
$scope.getOnlines = function () { |
|
return $http.post($scope.urlListOnlines + '&username=currentol', {}).then(function successCallback(response) { |
|
$scope.onlines = response.data; |
|
}, function errorCallback(response) { |
|
}); |
|
}; |
|
|
|
$scope.init = function () { |
|
$scope.listMessages(); |
|
$scope.pidMessages = window.setInterval($scope.listMessages, 3000); |
|
$scope.pidPingServer = window.setInterval($scope.pingServer, 5000); |
|
$scope.getAuthUsers(); |
|
$("#popeditor").on("show.bs.modal", function () { |
|
var height = $(window).height() - 200; |
|
$(this).find(".modal-body").css("max-height", height); |
|
}); |
|
}; |
|
|
|
$scope.scrollDown = function () { |
|
var pidScroll; |
|
pidScroll = window.setInterval(function () { |
|
$('.direct-chat-messages').scrollTop(window.Number.MAX_SAFE_INTEGER * 0.001); |
|
window.clearInterval(pidScroll); |
|
}, 100); |
|
}; |
|
|
|
$scope.clearHistory = function () { |
|
var lastMessage = $scope.getLastMessage(); |
|
var lastMessageId = lastMessage && lastMessage.id; |
|
lastMessageId = (lastMessageId - 1 >= 2) ? lastMessageId - 1 : lastMessageId; |
|
lastMessageId && ($scope.historyFromId = lastMessageId); |
|
}; |
|
|
|
$scope.openModal = function (e) { |
|
var mi = $('#popeditor').modal({backdrop: "static"}); |
|
$scope.editmsg(); |
|
}; |
|
|
|
$scope.playAudio = function () { |
|
$scope.beep && $scope.beep.play(); |
|
}; |
|
|
|
$scope.renderMessageBody = function (html) { |
|
return html; |
|
}; |
|
$scope.init(); |
|
}]); |
|
})(); |
|
</script> |
|
<style> |
|
.direct-chat-text { |
|
border-radius: 5px; |
|
position: relative; |
|
padding: 5px 10px; |
|
background: #FBFBFB; |
|
border: 1px solid var(--gray); |
|
margin: 5px 0 0 50px; |
|
color: var(--dark); |
|
} |
|
|
|
.direct-chat-msg, |
|
.direct-chat-text { |
|
display: block; |
|
word-wrap: break-word; |
|
} |
|
|
|
.direct-chat-img { |
|
border-radius: 50%; |
|
float: left; |
|
width: 40px; |
|
height: 40px; |
|
} |
|
|
|
.direct-chat-info { |
|
display: block; |
|
margin-bottom: 2px; |
|
font-size: 12px; |
|
} |
|
|
|
.direct-chat-msg { |
|
margin-bottom: 5px; |
|
} |
|
|
|
.direct-chat-messages { |
|
-webkit-transform: translate(0, 0); |
|
-ms-transform: translate(0, 0); |
|
-o-transform: translate(0, 0); |
|
transform: translate(0, 0); |
|
padding: 5px; |
|
height: calc(100vh - 175px); |
|
overflow: auto; |
|
word-wrap: break-word; |
|
} |
|
|
|
.direct-chat-text:before { |
|
border-width: 6px; |
|
margin-top: -6px; |
|
} |
|
|
|
.direct-chat-text:after { |
|
border-width: 5px; |
|
margin-top: -5px; |
|
} |
|
|
|
.direct-chat-text:after, |
|
.direct-chat-text:before { |
|
position: absolute; |
|
right: 100%; |
|
top: 15px; |
|
border: solid rgba(0, 0, 0, 0); |
|
border-right-color: #D2D6DE; |
|
content: ' '; |
|
height: 0; |
|
width: 0; |
|
pointer-events: none; |
|
} |
|
|
|
.direct-chat-warning .right > .direct-chat-text { |
|
background: rgba(251, 255, 178, 0.34); |
|
border-color: var(--danger); |
|
color: var(--black); |
|
} |
|
|
|
.right .direct-chat-text { |
|
margin-right: 50px; |
|
margin-left: 0; |
|
} |
|
|
|
.direct-chat-warning .right > .direct-chat-text:after, |
|
.direct-chat-warning .right > .direct-chat-text:before { |
|
border-left-color: #F39C12; |
|
} |
|
|
|
.right .direct-chat-text:after, |
|
.right .direct-chat-text:before { |
|
right: auto; |
|
left: 100%; |
|
border-right-color: rgba(0, 0, 0, 0); |
|
border-left-color: #D2D6DE; |
|
} |
|
|
|
.right .direct-chat-img { |
|
float: right; |
|
} |
|
|
|
.direct-chat-name { |
|
font-weight: 600; |
|
} |
|
|
|
.box-footer form { |
|
margin-bottom: 10px; |
|
} |
|
|
|
input, |
|
.btn, |
|
.alert, |
|
.modal-content { |
|
border-radius: 0 !important; |
|
} |
|
|
|
.sidebar { |
|
background-color: #f8f8ff; |
|
max-height: 95vh; |
|
margin-top: 5px; |
|
margin-right: 0; |
|
padding-right: 5px; |
|
overflow: auto; |
|
} |
|
|
|
.rtsidebar { |
|
background-color: #f8f8ff; |
|
max-height: 95vh; |
|
margin-top: 5px; |
|
margin-right: 0; |
|
overflow: auto; |
|
} |
|
|
|
.fixed-panel { |
|
height: 100%; |
|
padding: 5px 5px 0 5px; |
|
} |
|
|
|
h5 { |
|
font-size: 16px !important; |
|
} |
|
|
|
label { |
|
display: block; |
|
} |
|
|
|
legend { |
|
font-size: 14px; |
|
margin-bottom: 2px; |
|
background: var(--white); |
|
} |
|
|
|
.modal.modal-wide .modal-dialog { |
|
width: 75%; |
|
} |
|
|
|
.modal-wide .modal-body { |
|
overflow-y: auto; |
|
} |
|
</style> |
|
|
|
<body ng-controller="MsgAppCtrl"> |
|
<div class="container-fluid"> |
|
<!-- <h2 class="d-none">Secure Chat</h2> --> |
|
<div class="row"> |
|
<div class="col-md-2 sidebar"> |
|
<h5><span class="badge badge-primary"><?php echo xlt('Current Recipients'); ?></span></h5> |
|
<label ng-repeat="user in chatusers | unique : 'username'" ng-if="pusers.indexOf(user.recip_id) !== -1 && user.recip_id != me.sender_id"> |
|
<input type="checkbox" data-checklist-model="pusers" data-checklist-value="user.recip_id"> {{user.username}} |
|
</label> |
|
<h5><span class="badge badge-primary"><?php echo xlt('Available Recipients'); ?></span></h5> |
|
<span> |
|
<button id="chkall" class="btn btn-sm btn-success" ng-show="!isPortal" ng-click="checkAll()" type="button"><?php echo xlt('All{{Recipients}}'); ?></button> |
|
<button id="chknone" class="btn btn-sm btn-success" ng-show="!isPortal" ng-click="uncheckAll()" type="button"><?php echo xlt('None{{Recipients}}'); ?></button> |
|
</span> |
|
<label ng-repeat="user in chatusers | unique : 'username'" ng-show="!isPortal || (isPortal && user.dash)"> |
|
<input type="checkbox" data-checklist-model="pusers" data-checklist-value="user.recip_id"> {{user.username}} |
|
</label> |
|
</div> |
|
<div class="col-md-8 fixed-panel"> |
|
<div class="card direct-chat direct-chat-warning"> |
|
<div class="card-heading bg-dark text-light py-2"> |
|
<div class="clearfix btn-group ml-2"> |
|
<a class='btn btn-primary' href='./../patient/provider' ng-show='!isPortal'><?php echo xlt('Home'); ?></a> |
|
<a class="btn btn-secondary" href="" data-toggle="modal" data-target="#clear-history"><?php echo xlt('Clear history'); ?></a> |
|
</div> |
|
</div> |
|
<div class="card-body"> |
|
<div class="direct-chat-messages"> |
|
<div class="direct-chat-msg" ng-repeat="message in messages" ng-if="historyFromId < message.id" ng-class="{'right':!message.me}"> |
|
<div class="direct-chat-info clearfix"> |
|
<span class="direct-chat-name" ng-class="{'float-left':message.me,'float-right':!message.me}">{{message.username }}</span> |
|
<span class="direct-chat-timestamp " ng-class="{'float-left':!message.me,'float-right':message.me}">{{message.date }}</span> |
|
</div> |
|
<i class="direct-chat-img fa fa-hand-o-left" style="cursor: pointer; font-size: 24px" ng-show="!message.me" ng-click="makeCurrent(message)" title="<?php echo xla('Click to activate and send to this recipient.'); ?>"></i> |
|
<i class="direct-chat-img fa fa-hand-o-right" style="cursor: pointer; font-size:24px" ng-show="message.me" ng-click="makeCurrent(message)" title="<?php echo xla('Click to activate and send to this recipient.'); ?>"></i> |
|
|
|
<div class="direct-chat-text right"> |
|
<div class='px-0' title="<?php echo xla('Click to activate and send to this recipient.'); ?>" ng-click="makeCurrent(message)" ng-bind-html="renderMessageBody(message.message)"></div> |
|
</div> |
|
</div> |
|
</div> |
|
<div class="card-footer box-footer-hide"> |
|
<form id='msgfrm' ng-submit="saveMessage()"> |
|
<div class="input-group"> |
|
<input type="text" placeholder="<?php echo xla('Type Message...'); ?>" id="msgedit" autofocus="autofocus" class="form-control" ng-model="me.message" ng-enter="saveMessage()"> |
|
<span class="input-group-append"> |
|
<button type="submit" class="btn btn-danger btn-flat"><?php echo xlt('Send'); ?></button> |
|
<button type="button" class="btn btn-success btn-flat" ng-click="openModal(event)"><?php echo xlt('Edit'); ?></button> |
|
</span> |
|
</div> |
|
</form> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
<div class="col-md-2 rtsidebar"> |
|
<h5><span class="badge badge-primary"><?php echo xlt("Online Users"); ?> : {{ online.total || '0' }}</span> |
|
</h5> |
|
<label ng-repeat="ol in onlines | unique : 'username'"> |
|
<input type="checkbox" data-checklist-model="onlines" data-checklist-value="ol"> {{ol.username}} |
|
</label> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<div class="modal modal-wide fade" id="popeditor"> |
|
<div class="modal-dialog modal-lg"> |
|
<div class="modal-content"> |
|
<form> |
|
<div class="modal-header"> |
|
<h5 class='modal-title'><?php echo xlt('You may send Message with Image or Video'); ?></h5> |
|
<button type="button" class="close" data-dismiss="modal"> |
|
<span aria-hidden="true">×</span> |
|
<span class="sr-only"><?php echo xlt('Close'); ?></span> |
|
</button> |
|
</div> |
|
<div class="modal-body"> |
|
<textarea cols='80' rows='10' id='messageContent' name='content'></textarea> |
|
</div> |
|
<div class="modal-footer"> |
|
<button type="button" class="btn btn-sm" data-dismiss="modal"><?php echo xlt('Dismiss'); ?></button> |
|
<button type="button" class="btn btn-success" data-dismiss="modal" ng-click="saveedit()"><?php echo xlt('Send It'); ?></button> |
|
</div> |
|
</form> |
|
</div> |
|
</div> |
|
</div> |
|
<div class="modal" id="clear-history"> |
|
<div class="modal-dialog"> |
|
<div class="modal-content"> |
|
<form> |
|
<div class="modal-header"> |
|
<button type="button" class="close" data-dismiss="modal"> |
|
<span aria-hidden="true">×</span> |
|
<span class="sr-only"><?php echo xlt('Close'); ?></span> |
|
</button> |
|
<h4 class="modal-title"><?php echo xlt('Chat history'); ?></h4> |
|
</div> |
|
<div class="modal-body"> |
|
<label class="radio"><?php echo xlt('Are you sure you want to clear chats session history?'); ?></label> |
|
</div> |
|
<div class="modal-footer"> |
|
<button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal"><?php echo xlt('Cancel'); ?></button> |
|
<button type="button" class="btn btn-sm btn-primary" data-dismiss="modal" ng-click="clearHistory()"><?php echo xlt('Accept'); ?></button> |
|
</div> |
|
</form> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
</body> |
|
</html>
|
|
|