|
@@ -0,0 +1,348 @@
|
|
|
+@extends('app.my-account.admin.users.single')
|
|
|
+
|
|
|
+@section('details')
|
|
|
+
|
|
|
+ <div>
|
|
|
+ <h4><b>Messages</b></h4>
|
|
|
+ <script src="https://static.opentok.com/v2/js/opentok.min.js"></script>
|
|
|
+ <div class="container">
|
|
|
+ <div class="custom-card w-100 p-0 patients-content">
|
|
|
+ <div class="mcp-theme-1 im-body" id="messages">
|
|
|
+ <div class="card overflow-hidden border-0 h-100">
|
|
|
+
|
|
|
+ <div class="msg-header p-3 d-flex align-items-center shadow-sm">
|
|
|
+ <strong class="">
|
|
|
+ <i class="fas fa-comments mr-2"></i>
|
|
|
+ Messages
|
|
|
+ </strong>
|
|
|
+ </div>
|
|
|
+ <div class="card-body p-0 h-100">
|
|
|
+
|
|
|
+ <div class="im-container h-100">
|
|
|
+ <div class="im-rhs p-2">
|
|
|
+ @if (!$messages || !count($messages))
|
|
|
+ <div class="py-4 text-center text-secondary">
|
|
|
+ <h3 class="mb-0"><i class="far fa-comment-dots"></i></h3>
|
|
|
+ No messages yet!
|
|
|
+ </div>
|
|
|
+ @endif
|
|
|
+ <div class="im-messages">
|
|
|
+ <div class="mh-100 overflow-auto opacity-0" id="im-scroller">
|
|
|
+ <?php $messageDates = []; ?>
|
|
|
+ @foreach ($messages as $k => $message)
|
|
|
+ @if (!in_array(friendly_date($message->created_at), $messageDates))
|
|
|
+ <?php array_push($messageDates, friendly_date($message->created_at)); ?>
|
|
|
+ <div class="text-center my-4">
|
|
|
+ <span style="background:#c2efff"
|
|
|
+ class="py-1 px-3 text-secondary rounded text-sm">{{ friendly_date_est($message->created_at) }}</span>
|
|
|
+ </div>
|
|
|
+ @endif
|
|
|
+ <div class="d-flex align-items-start">
|
|
|
+ @if ($message->from_user_id !== $performer->user->id)
|
|
|
+ <div class="">
|
|
|
+ @if (!$message->is_removed)
|
|
|
+ @if ($k == 0 || $messages[$k - 1]->from_user_id !== $messages[$k]->from_user_id)
|
|
|
+ <!-- remove unecessary timestamps -->
|
|
|
+ <div class="circle-icon">
|
|
|
+ {{ mb_substr($message->fromUser->name_first, 0, 1) }}
|
|
|
+ </div>
|
|
|
+ @else
|
|
|
+ <div class="circle-icon op">
|
|
|
+ {{ mb_substr($message->fromUser->name_first, 0, 1) }}
|
|
|
+ </div>
|
|
|
+ @endif
|
|
|
+ @endif
|
|
|
+ </div>
|
|
|
+ @endif
|
|
|
+ <div class="w-100">
|
|
|
+ <div class="im-message mt-0 pr-5 {{ $message->from_user_id === $performer->user->id ? 'sent' : 'received' }}"
|
|
|
+ data-uid="{{ $message->uid }}"
|
|
|
+ data-mark-as-read="{{ !$message->is_read ? 1 : 0 }}">
|
|
|
+ <div class="im-message-sender align-items-center">
|
|
|
+ @if (!$message->is_removed)
|
|
|
+ @if ($k == 0 || $messages[$k - 1]->from_user_id !== $messages[$k]->from_user_id)
|
|
|
+ <!-- remove unecessary timestamps -->
|
|
|
+ @if ($message->from_user_id !== $performer->user->id)
|
|
|
+ <small
|
|
|
+ class="mr-2 text-secondary">{{ $message->fromUser->displayName() }},</small>
|
|
|
+ @endif
|
|
|
+ <small
|
|
|
+ class="header-item text-secondary text-sm">{{ friendly_time_by_time_zone($message->created_at) }}</small>
|
|
|
+ @endif
|
|
|
+ @if ($performer->user->id == $message->created_by_user_id && $message->content_text)
|
|
|
+ <div class="header-item">
|
|
|
+ <div moe large relative>
|
|
|
+ @if ($k == 0 || $messages[$k - 1]->from_user_id !== $messages[$k]->from_user_id)
|
|
|
+ <a href="#" start show><i
|
|
|
+ class="fa fa-edit on-hover-opaque text-pry text-sm hidden edit"
|
|
|
+ style="top:18px;"></i></a>
|
|
|
+ @else
|
|
|
+ <a href="#" start show><i
|
|
|
+ class="fa fa-edit on-hover-opaque text-pry text-sm hidden edit"></i></a>
|
|
|
+ @endif
|
|
|
+ <form url="/api/message/editContent"
|
|
|
+ class="text-left" right>
|
|
|
+ <input type="hidden" name="uid"
|
|
|
+ value="{{ $message->uid }}">
|
|
|
+ <div class="mb-2">
|
|
|
+ <label class="mb-1 text-sm">Edit
|
|
|
+ Message</label>
|
|
|
+ <textarea name="contentText" rows="3" class="form-control form-control-sm">{{ $message->content_text }}</textarea>
|
|
|
+ </div>
|
|
|
+ <div class="mt-3">
|
|
|
+ <button submit
|
|
|
+ class="btn btn-sm btn-primary mr-2">Submit</button>
|
|
|
+ <button cancel
|
|
|
+ class="btn btn-default btn-sm border">Cancel</button>
|
|
|
+ </div>
|
|
|
+ </form>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ @endif
|
|
|
+ @if ($message->from_user_id === $performer->user->id)
|
|
|
+ <span class="header-item hidden delete">
|
|
|
+ <a href="#" native class="remove-message"
|
|
|
+ data-message-uid="{{ $message->uid }}"><i
|
|
|
+ class="fa fa-trash-alt text-danger text-sm"></i></a>
|
|
|
+ </span>
|
|
|
+ @endif
|
|
|
+ @endif
|
|
|
+ </div>
|
|
|
+ @if ($message->is_removed)
|
|
|
+ <div class="im-message-content text-secondary font-italic">
|
|
|
+ This message was removed.</div>
|
|
|
+ @else
|
|
|
+ @if ($message->content_text)
|
|
|
+ <?php
|
|
|
+ $message->content_text = preg_replace_callback(
|
|
|
+ '~(?:http|ftp)s?://(?:www\.)?([a-z0-9.-]+\.[a-z]{2,3}(?:/\S*)?)~i',
|
|
|
+ function ($match) {
|
|
|
+ return '<a native target="_blank" href="' . $match[0] . '">' . $match[0] . '</a>';
|
|
|
+ },
|
|
|
+ $message->content_text,
|
|
|
+ );
|
|
|
+ ?>
|
|
|
+ <div class="im-message-content">{!! $message->content_text !!}
|
|
|
+ </div>
|
|
|
+ @endif
|
|
|
+ @endif
|
|
|
+ @if (count($message->attachments) && !$message->is_removed)
|
|
|
+ <div class="attachments-container mt-1 d-flex align-items-center flex-wrap {{ $message->from_user_id === $performer->user->id ? 'justify-content-end' : 'justify-content-start' }}"
|
|
|
+ data-message-uid="{{ $message->uid }}"
|
|
|
+ data-attachments-loaded="0">
|
|
|
+ <span class="my-1 text-primary c-pointer text-sm">
|
|
|
+ <i class="fa fa-paperclip"></i>
|
|
|
+ {{ count($message->attachments) }}
|
|
|
+ attachment{{ count($message->attachments) === 1 ? '' : 's' }}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ @endif
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ @endforeach
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ @if ($toUser)
|
|
|
+ <div class="im-input">
|
|
|
+ <div class="d-flex align-items-end">
|
|
|
+ <div class="msg-input">
|
|
|
+ <textarea placeholder="Enter your message here..."></textarea>
|
|
|
+ <button class="btn btn-sm btn-input" id="im-btn-send"><i
|
|
|
+ class="fa fa-paper-plane"></i></button>
|
|
|
+ </div>
|
|
|
+ <div class="fabs ml-2">
|
|
|
+ <button class="btn btn-sm btn-info ml-2" id="im-btn-select-file"><i
|
|
|
+ class="fa fa-paperclip"></i></button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="d-flex align-items-end flex-wrap" id="selected-files">
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ @endif
|
|
|
+
|
|
|
+ <div>
|
|
|
+ {{ $messages->withQueryString()->links() }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <script>
|
|
|
+ $(document).ready(function() {
|
|
|
+
|
|
|
+ setTimeout(function() {
|
|
|
+ jQuery('.mark-as-read').click();
|
|
|
+ }, 1000);
|
|
|
+
|
|
|
+ let inProgress = false;
|
|
|
+
|
|
|
+ function showSelectedFiles() {
|
|
|
+ $('#selected-files').empty();
|
|
|
+ $('.im-file-upload').each(function() {
|
|
|
+ if (this.files && this.files.length) {
|
|
|
+ for (let i = 0; i < this.files.length; i++) {
|
|
|
+ $('#selected-files').append($('<div class="selected-file" data-id="' + this.id +
|
|
|
+ '" title="Click to remove">').text(this.files[i].name));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ function hasError(_data) {
|
|
|
+ let msg = 'Unknown error!';
|
|
|
+ if (_data) {
|
|
|
+ if (_data.success) return false;
|
|
|
+ else if (_data.message) msg = _data.message;
|
|
|
+ }
|
|
|
+ toastr.error(msg);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ function doSend(_elem) {
|
|
|
+ if (inProgress) return false;
|
|
|
+ inProgress = true;
|
|
|
+ showMask();
|
|
|
+ let text = $.trim(_elem.value);
|
|
|
+ let formData = new FormData();
|
|
|
+ formData.set('fromUserUid', '{{ $performer->user->uid }}');
|
|
|
+ formData.set('toUserUid', '{{ isset($toUser) ? $toUser->uid : null }}');
|
|
|
+ formData.set('contentText', text);
|
|
|
+
|
|
|
+ let hasFiles = false;
|
|
|
+ $('.im-file-upload').each(function() {
|
|
|
+ if (this.files && this.files.length) {
|
|
|
+ for (let i = 0; i < this.files.length; i++) {
|
|
|
+ formData.append('attachments', this.files[i]);
|
|
|
+ hasFiles = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ if (!hasFiles && !text) { // either attachment or text or both should be there
|
|
|
+ inProgress = false;
|
|
|
+ hideMask();
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ jQuery.ajax('/api/message/create', {
|
|
|
+ dataType: 'json',
|
|
|
+ data: formData,
|
|
|
+ processData: false,
|
|
|
+ contentType: false,
|
|
|
+ type: 'POST',
|
|
|
+ }).done(function(_data) {
|
|
|
+ if (!hasError(_data)) {
|
|
|
+ fastReload();
|
|
|
+ } else {
|
|
|
+ $('.im-input textarea').val('');
|
|
|
+ inProgress = false;
|
|
|
+ hideMask();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ function init() {
|
|
|
+ @if (isset($user))
|
|
|
+ $('.im-input textarea').on('keydown', function(_e) {
|
|
|
+ if (_e.which === 13 && !_e.shiftKey) {
|
|
|
+ return doSend(this);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ $('#im-btn-send').click(function() {
|
|
|
+ return doSend($('.im-input textarea')[0]);
|
|
|
+ });
|
|
|
+
|
|
|
+ $('#plusBtn').click(function() {
|
|
|
+ $('.hide').toggle();
|
|
|
+ $('.show').toggle();
|
|
|
+ });
|
|
|
+
|
|
|
+ $('#im-btn-select-file').click(function() {
|
|
|
+ let fiID = Math.floor(Math.random() * 10000);
|
|
|
+ let fileInput = $('<input type="file" class="d-none im-file-upload" id="fu-' +
|
|
|
+ fiID + '">');
|
|
|
+ $('.im-input').append(fileInput)
|
|
|
+ fileInput.click();
|
|
|
+ });
|
|
|
+
|
|
|
+ $(document).on('change', '.im-file-upload', function() {
|
|
|
+ showSelectedFiles();
|
|
|
+ });
|
|
|
+
|
|
|
+ $(document)
|
|
|
+ .off('click', '.selected-file')
|
|
|
+ .on('click', '.selected-file', function() {
|
|
|
+ $('#' + $(this).attr('data-id')).remove();
|
|
|
+ showSelectedFiles();
|
|
|
+ });
|
|
|
+
|
|
|
+ $(document)
|
|
|
+ .off('click.load-attachments', '.attachments-container[data-attachments-loaded="0"]>span')
|
|
|
+ .on('click.load-attachments', '.attachments-container[data-attachments-loaded="0"]>span',
|
|
|
+ function() {
|
|
|
+ let container = $(this).closest('.attachments-container');
|
|
|
+ if (inProgress) return false;
|
|
|
+ inProgress = true;
|
|
|
+ $.get('/admin/users/view/{{$user->uid}}/messages/' + container.attr(
|
|
|
+ 'data-message-uid') + '/attachments', (_data) => {
|
|
|
+ container.html(_data).attr('data-attachments-loaded', 1);
|
|
|
+ }).then(function() {
|
|
|
+ inProgress = false;
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ $(document)
|
|
|
+ .off('click', '.mark-as-read')
|
|
|
+ .on('click', '.mark-as-read', function() {
|
|
|
+ $.post('/api/message/markRead', {
|
|
|
+ uid: $(this).attr('data-message-uid')
|
|
|
+ }, () => {
|
|
|
+ $(this).replaceWith(
|
|
|
+ '<i class="fa fa-check text-secondary on-hover-opaque text-sm"></i>'
|
|
|
+ );
|
|
|
+ let unreadBadge = $('.unread-badge[data-user-id="' +
|
|
|
+ {{ $user->id }} + '"]').first();
|
|
|
+ if (unreadBadge.length) {
|
|
|
+ let newCount = (+unreadBadge.text()) - 1;
|
|
|
+ if (newCount) {
|
|
|
+ unreadBadge.text(newCount);
|
|
|
+ } else {
|
|
|
+ unreadBadge.remove();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }, 'json');
|
|
|
+ return false;
|
|
|
+ });
|
|
|
+
|
|
|
+ $(document)
|
|
|
+ .off('click', '.remove-message')
|
|
|
+ .on('click', '.remove-message', function() {
|
|
|
+ $.post('/api/message/markAsRemoved', {
|
|
|
+ uid: $(this).attr('data-message-uid')
|
|
|
+ }, () => {
|
|
|
+ $(this).closest('.im-message').html(
|
|
|
+ '<div class="im-message-content text-secondary font-italic">This message was removed.</div>'
|
|
|
+ );
|
|
|
+ }, 'json');
|
|
|
+ return false;
|
|
|
+ });
|
|
|
+
|
|
|
+ var imScroller = document.getElementById("im-scroller");
|
|
|
+ imScroller.scrollTop = imScroller.scrollHeight;
|
|
|
+ $(imScroller).removeClass('opacity-0');
|
|
|
+ @endif
|
|
|
+
|
|
|
+ }
|
|
|
+ init();
|
|
|
+ });
|
|
|
+ </script>
|
|
|
+ </div>
|
|
|
+
|
|
|
+@endsection
|