Файловый менеджер - Редактировать - /home/clickysoft/public_html/somni.clickysoft.net/resources/views/chat/message.blade.php
Назад
@extends( $user->roles()->where('title', 'Tenant')->exists() ? 'tenant.layouts.tenant' : 'landlord.layouts.landlord' ) @section('title', 'Messages - SOMNI') @section('content') <div class="db-backdrop"></div> <div class="main-section"> <div class="tooltip-text" id="tooltip1" tool-tip="1"> <div class="tooltip-close"> <button class="tt-close"><img src="{{ asset('/images/close-tt.svg') }}" alt="" class="img-fluid"></button> </div> <div class="tooltip-head"> <h4>Navigation</h4> <p>From here you can view a quick snapshot of occupancy rates, upcoming maintenance, and financial summaries.</p> </div> <div class="hide-next-cta"> <div class="hide-tips"> <button class="hide-tips"><img src="{{ asset('/images/hide-tt.svg') }}" alt="" class="hide-tt">Hide these tips</button> </div> <div class="next-tips"> <button class="next-tip-btn">Next</button> </div> </div> </div> @if ($user->roles()->where('title', 'Tenant')->exists()) <x-tenant-side-nav /> @else <x-landlord-side-nav /> @endif <main class="layout-main"> <div class="content-wrapper"> <section class="profile-edit"> <div class="container-fluid custom-container"> <div class="row "> <div class="col-md-12"> <div class="main-db-layout"> @if ($user->roles()->where('title', 'Tenant')->exists()) <div class="mobile-nav-view tenan-view"> <!--here component--> {{-- @dd($user) --}} {{-- <x-user.dropdown :user="$user" /> --}} <x-tenant-mobile-notification :notifications=$notifications :user=$user :nCount=$nCount /> </div> @else <x-landlord-mobile-widget :user="$user" :notifications="$notifications" :nCount="$nCount" /> @endif {{-- <div class="mobile-nav-view"> <div class="db-nav"> <ul> @if ($user->roles()->where('title', 'Landlord')->exists()) <li><a href="javascript:void(0)">All Properties</a></li> <li><a href="javascript:void(0)">Add Property</a></li> @endif <!-- <li><a href="javascript:void(0)" class="active">Home</a></li> --> </ul> </div> <!--here component--> <x-user.dropdown :user="$user" /> </div> --}} <div class="row"> <div class="col-md-12 col-lg-12"> <div class="mod-heads"> <h3> Messages </h3> <p>Stay connected and informed – manage your messages seamlessly in one place.</p> </div> <div class="mesage-box"> <div class="tabs-sec"> <div class="row"> <div class="col-md-12 col-lg-3"> <div class="message-left"> <div class="user-chat"> <div class="user-thumb-name"> <div class="user-thumb"> <p>R</p> <span class="chat-dot active"></span> </div> <div class="user-thumb-name-cont"> <h5>{{ Auth::user()->name }}</h5> <p class="online">Online</p> </div> </div> </div> <ul class="nav nav-tabs message-tabs" role="tablist"> @foreach ($combinedData as $key => $data) <li class="nav-item" role="presentation"> <button class="nav-link {{ $key === 0 ? 'active' : '' }}" id="home-{{ $key }}-tab" data-bs-toggle="tab" data-bs-target="#home-{{ $key }}" type="button" role="tab" aria-controls="home-{{ $key }}" aria-selected="true"> <div class="user-chat-selection"> <div class="user-thumb"> <p>C</p> <span class="chat-dot active"></span> </div> <div class="user-thumb-name-cont"> <h5>{{ $data['name'] }} </h5> <span class="chat-message-counter counter-{{ $data['sender_id'] }}"> {{ \App\Models\ChatMessage::where('receiver_id', auth()->user()->id)->where('sender_id', $data['sender_id'])->where('status', 'unread')->count() }} </span> <p class="online online-{{ $data['sender_id'] }}" style="display: none">Online </p> <p class="offline offline-{{ $data['sender_id'] }}" style="">offline </p> <span class="typing-tc typing-tc-{{ $data['sender_id'] }}-{{ Auth::user()->id }}" style="display: none">typing.... </span> </div> </div> </button> </li> @endforeach </ul> <div class="need-help-button hide-respnsive"> <a href="/#contact_bottom2" target="_blank" class="help-btn need_help">Need Help?</a> </div> </div> </div> <div class="col-md-12 col-lg-9 d-flex flex-column"> <div class="tab-content"> @foreach ($combinedData as $data) <div class="tab-pane fade {{ $loop->first ? 'show active' : '' }}" id="home-{{ $loop->index }}" role="tabpanel" aria-labelledby="home-{{ $loop->index }}-tab"> <div class="message-panel" id="msg-panel{{ $data['sender_id'] }}"> <div class="force-flow h-100"> <div class="chat-right-main"> <div class="sender-left-{{ $data['sender_id'] }}-{{ Auth::user()->id }} unread" id="sender-left-{{ $data['sender_id'] }}-{{ Auth::user()->id }}"> @foreach ($data['messages'] as $message) @if ($message->status === 'read') @if ($message->sender_id == auth()->id()) <div class="chat-message-right read"> <div class="flex-column"> <span class="chat-username-time">Me, {{ $message->created_at->diffForHumans() }}</span> <div class="cht-box-right"> @if ($message->message) <p>{{ $message->message }} </p> @endif @if ($message->hasMedia('file')) <img src="{{ $message->getFirstMediaUrl('file') }}" alt="File Image" style="max-width: 200px; max-height: 100px;"> @endif </div> </div> </div> @else <div class="chat-message-left read"> <span class="chat-username-time">{{ $data['name'] }}, {{ $message->created_at->diffForHumans() }}</span> <div class="cht-box"> @if ($message->message) <p>{{ $message->message }} </p> @endif @if ($message->hasMedia('file')) <img src="{{ $message->getFirstMediaUrl('file') }}" alt="File Image" style="max-width: 200px; max-height: 100px;"> @endif </div> </div> @endif @endif @endforeach <div class="unread-bar-divider"> <h4>Unread <span></span></h4> </div> @foreach ($data['messages'] as $message) @if ($message->status === 'unread') {{-- TODO:when relation table unread-message--- to unread-message --}} @if ($message->sender_id == auth()->id()) <div class="chat-message-right unread-message---" data-message-id="{{ $message->id }}"> <div class="flex-column"> <span class="chat-username-time">Me, {{ $message->created_at->diffForHumans() }}</span> <div class="cht-box-right"> @if ($message->message) <p>{{ $message->message }} </p> @endif @if ($message->hasMedia('file')) <img src="{{ $message->getFirstMediaUrl('file') }}" alt="File Image" style="max-width: 200px; max-height: 100px;"> @endif </div> </div> </div> @else <div class="chat-message-left unread-message-left unread-message" data-message-id="{{ $message->id }}"> <span class="chat-username-time">{{ $data['name'] }}, {{ $message->created_at->diffForHumans() }}</span> <div class="cht-box"> @if ($message->message) <p>{{ $message->message }} </p> @endif @if ($message->hasMedia('file')) <img src="{{ $message->getFirstMediaUrl('file') }}" alt="File Image" style="max-width: 200px; max-height: 100px;"> @endif </div> <br> </div> @endif @endif @endforeach <div class="chat-message-left"> <div class="typing typing-{{ $data['sender_id'] }}-{{ Auth::user()->id }}" style="display:none;"> <div class="dot"></div> <div class="dot"></div> <div class="dot"></div> </div> </div> </div> </div> </div> </div> <div class="message-send-box"> <div class="strt-type-field"> <input type="text" class="message-input" placeholder="Start typing here" data-receiver-user-id="{{ $data['sender_id'] }}"> </div> <div class="attatch-send"> <div class="attatchment-icon"> <label for="fileInput-{{ $data['sender_id'] }}-{{ Auth::user()->id }}"> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="21" viewBox="0 0 18 21" fill="none"> <path d="M8.49782 8.88379L5.18235 12.3374C4.33841 13.2165 4.33841 14.5979 5.18235 15.4771C6.02629 16.3562 7.35248 16.3562 8.19641 15.4771L15.4302 7.94189C16.9372 6.37207 16.9372 3.86034 15.4302 2.29052C13.9231 0.720694 11.5119 0.720694 10.0049 2.29052L2.16828 10.4536C-0.00184255 12.7142 -0.00184243 16.3562 2.16828 18.6167C4.33841 20.8773 7.83473 20.8773 10.0049 18.6167L13.9231 14.5352" stroke="#079E00" stroke-linecap="round" stroke-linejoin="round" /> </svg> </label> <input type="file" accept=".png, .jpg, .jpeg" id="fileInput-{{ $data['sender_id'] }}-{{ Auth::user()->id }}" style="display: none" onchange="handleFilePreview(this, '{{ $data['sender_id'] }}', '{{ Auth::user()->id }}')"> </div> <div id="filePreview-{{ $data['sender_id'] }}-{{ Auth::user()->id }}" style="display: none;"></div> <div class="send-message-button"> <button type="button" data-receiver-user-id="{{ $data['sender_id'] }}" class="smssg-btn">Send</button> </div> </div> </div> <div class="need-help-button show-respnsive"> <button type="button" class="help-btn">Need Help?</button> </div> </div> @endforeach </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </section> </div> </main> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <script src="https://www.gstatic.com/firebasejs/8.3.2/firebase.js"></script> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <link href="https://cdn.jsdelivr.net/npm/sweetalert2@11.7.27/dist/sweetalert2.min.css" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11.7.27/dist/sweetalert2.all.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"> </script> <script src="{{ asset('/js/global.js') }}"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/js/toastr.min.js"></script> <script src="https://cdn.socket.io/4.6.0/socket.io.min.js"></script> <script> @if (!empty($verification)) toastr.options = { "closeButton": true, "progressBar": true } toastr.warning("{{ $verification }}"); @endif </script> <script> function handleFilePreview(input, senderId, receiverId) { const filePreview = document.getElementById('filePreview-' + senderId + '-' + receiverId); filePreview.innerHTML = ''; const file = input.files[0]; if (file) { const reader = new FileReader(); reader.onload = function(e) { const preview = document.createElement('img'); preview.src = e.target.result; preview.style.maxWidth = '200px'; preview.style.maxHeight = '100px'; filePreview.appendChild(preview); filePreview.style.display = 'block'; }; reader.readAsDataURL(file); } } const messagesPanel = document.querySelector('.message-panel'); function scrollToBottom() { // messagesPanel.scrollTop = messagesPanel.scrollHeight; let parentDiv = messagesPanel.parentElement; // console.log('parent is, ',parentDiv); // Check if the direct parent has the class 'active' if (parentDiv.classList.contains('active')) { // console.log('inside if',parentDiv); // Scroll to the bottom only if the parent has the 'active' class messagesPanel.scrollTop = messagesPanel.scrollHeight; } parentDiv = ''; } $(document).ready(function(){ scrollToBottom(); }); </script> <script> let ip_address = "{{ env('SOCKET_URL') }}"; let socket_port = '5000'; let host = ''; const senderId = {{ auth()->id() }}; // let socket = io("wss://" + ip_address + ':' + socket_port); const environment = "{{ env('APP_ENV') }}"; if (environment == 'local' || environment == 'Local') { host = "ws://" + ip_address + ':' + socket_port; } else { host = "wss://"+ ip_address; //+ ':' + socket_port; } const queryParams = { userId: senderId }; //const socket = io({ // path: "/socket.io/", // secure: true //}); const socket = io(host, { //upgrade: false, path: "/socket.io/", query: queryParams, secure: true, //reconnection: false, //rejectUnauthorized: false }); socket.once("connect", () => { socket.on("online", (userId) => { // console.log(userId, "Is Online!"); jQuery('.online-' + userId).css("display", "flex"); jQuery('.offline-' + userId).css("display", "none"); }); socket.on("offline", (userId) => { jQuery('.online-' + userId).css("display", "none"); jQuery('.offline-' + userId).css("display", "flex"); }); }); const messageInputList = document.querySelectorAll('.message-input'); messageInputList.forEach((messageInput) => { messageInput.addEventListener('keydown', (e) => { const inputField = e.target; const button = inputField.closest('.message-send-box').querySelector('.smssg-btn'); if (button) { const receiverId = button.getAttribute('data-receiver-user-id'); socket.emit('typing', senderId, receiverId); } }); }); document.querySelectorAll('.message-input').forEach((button) => { button.addEventListener('keydown', (event) => { if (event.key === 'Enter') { // console.log('HEEOOO'); const container = button.closest('.message-send-box'); const messageInput = container.querySelector('.message-input'); const message = messageInput.value; const receiverId = button.getAttribute('data-receiver-user-id'); // console.log('#fileInput' + '-' + receiverId + '-' + senderId); const fileInput = container.querySelector('#fileInput' + '-' + receiverId + '-' + senderId); // console.log(fileInput); let messageContainer = document.getElementById('msg-panel' + receiverId); // messageContainer.scrollTop = messageContainer.scrollHeight; // let message = messageInput.value; let file = ''; if(fileInput.files[0]){ file = fileInput.files[0]; } const formData = new FormData(); formData.append('sender_id', senderId); formData.append('_token', '{{ csrf_token() }}'); formData.append('receiver_id', receiverId); formData.append('message', message); formData.append('file', file); socket.emit('private chat message', file, message, senderId, receiverId); // console.log('Current :',file); var html = ''; if(file){ const blob = new Blob([file]); const dataUrl = URL.createObjectURL(blob); html = '<div class="chat-message-right"><div class="flex-column"><span class="chat-username-time">Me, 0 second ago</span><div class="cht-box-right"><p>' + message + '</p><img src="' + dataUrl + '" alt="Received Image" class="chat_file" /></div></div>'; }else{ html = '<div class="chat-message-right"><div class="flex-column"><span class="chat-username-time">Me, 0 second ago</span><div class="cht-box-right"><p>' + message + '</p></div></div>'; } // $('.unread').append(html); selector_box = `.sender-left-${receiverId}-${senderId}`; // console.log('This is bahar wala kaam ', $(selector_box).attr('class')); $('div#sender-left-' + receiverId + '-' + senderId).append(html); filePreview = document.getElementById('filePreview-' + receiverId + '-' + senderId); filePreview.innerHTML = ''; $.ajax({ type: 'POST', url: '{{ route('send.message') }}', data: formData, processData: false, contentType: false, success: function(response) { // console.log('Message saved successfully'); }, error: function(error) { console.error('Failed to save message'); } }); messageInput.value = ''; fileInput.value = ''; scrollToBottom(); } }); }); document.querySelectorAll('.smssg-btn').forEach((button) => { button.addEventListener('click', () => { const container = button.closest('.message-send-box'); const messageInput = container.querySelector('.message-input'); const message = messageInput.value; const receiverId = button.getAttribute('data-receiver-user-id'); const fileInput = container.querySelector('#fileInput' + '-' + receiverId + '-' + senderId); let messageContainer = document.getElementById('msg-panel' + receiverId); // messageContainer.scrollTop = messageContainer.scrollHeight; // let message = messageInput.value; let file = fileInput.files[0]; const formData = new FormData(); formData.append('sender_id', senderId); formData.append('_token', '{{ csrf_token() }}'); formData.append('receiver_id', receiverId); formData.append('message', message); formData.append('file', file); socket.emit('private chat message', file, message, senderId, receiverId); // console.log('Current :',file); var html = ''; if(file){ const blob = new Blob([file]); const dataUrl = URL.createObjectURL(blob); html = '<div class="chat-message-right"><div class="flex-column"><span class="chat-username-time">Me, 0 second ago</span><div class="cht-box-right"><p>' + message + '</p><img src="' + dataUrl + '" alt="Received Image" class="chat_file" /></div></div>'; }else{ html = '<div class="chat-message-right"><div class="flex-column"><span class="chat-username-time">Me, 0 second ago</span><div class="cht-box-right"><p>' + message + '</p></div></div>'; } // $('.unread').append(html); selector_box = `.sender-left-${receiverId}-${senderId}`; // console.log('This is bahar wala kaam ', $(selector_box).attr('class')); $('div#sender-left-' + receiverId + '-' + senderId).append(html); filePreview = document.getElementById('filePreview-' + receiverId + '-' + senderId); filePreview.innerHTML = ''; $.ajax({ type: 'POST', url: '{{ route('send.message') }}', data: formData, processData: false, contentType: false, success: function(response) { // console.log('Message saved successfully'); }, error: function(error) { console.error('Failed to save message'); } }); messageInput.value = ''; fileInput.value = ''; scrollToBottom(); }); }); socket.on('private chat message', (file, message, senderId, receiverId) => { // console.log('Private chat called with senderId:', senderId, 'receiverId:', receiverId); $.get('/chat-user-data', (data) => { var userData = data.userData; var serverTime = data.serverTime; var html = ''; var selector_box = ''; // console.log('Ths is file',file); if(file){ const blob = new Blob([file]); const dataUrl = URL.createObjectURL(blob); html = '<div class="chat-message-left"><span class="chat-username-time">' + userData.name + ', ' + serverTime + '</span><div class="cht-box"><p>' + message + '</p><img src="' + dataUrl + '" alt="Received Image" class="chat_file" /></div></div>'; }else{ html = '<div class="chat-message-left"><span class="chat-username-time">' + userData.name + ', ' + serverTime + '</span><div class="cht-box"><p>' + message + '</p></div></div>'; } // console.log('This is the msg box selector ',selector_box = `#sender-left-${senderId}-${receiverId}`); selector_box = '.sender-left-' + senderId + '-' + receiverId; // selector_box = `#sender-left-${senderId}-${receiverId}`; // console.log('this is the tag: ',$(selector_box)); $(selector_box).append(html); let messageContainer = document.getElementById('msg-panel' + receiverId); scrollToBottom(); // messageContainer.scrollTop = messageContainer.scrollHeight; }); }); socket.on('typing', (senderId, receiverId) => { const typingIndicator = document.querySelector('.typing-' + senderId + '-' + receiverId); const typingIndicatorTc = document.querySelector('.typing-tc-' + senderId + '-' + receiverId); var typingIndicatorHtml = '<div class="chat-message-left"><div class="typing"><div class="dot"></div> <div class="dot"></div><div class="dot"></div></div></div>'; // console.log($('.sender-left-' + senderId + '-' + receiverId + ' .typing').length); if ($('.sender-left-' + senderId + '-' + receiverId + ' .typing').length === 0) { $('.sender-left-' + senderId + '-' + receiverId).append(typingIndicatorHtml); } let messageContainer = document.getElementById('msg-panel' + senderId); messageContainer.scrollTop = messageContainer.scrollHeight; if (typingIndicatorTc) { typingIndicatorTc.style.display = 'block'; } setTimeout(() => { $('.sender-left-' + senderId + '-' + receiverId + ' .typing').remove(); typingIndicatorTc.style.display = 'none'; }, 3000); }); </script> <script> document.addEventListener("DOMContentLoaded", function() { let io; // Define io in a higher scope $('button[data-bs-toggle="tab"]').on('shown.bs.tab', function(e) { // Delay the setup to ensure the new tab content is fully rendered setTimeout(function() { setupIntersectionObserver(); }, 1000); }); function reportIntersection(entries) { entries.forEach(entry => { if (entry.isIntersecting) { var messageId = entry.target.getAttribute('data-message-id'); // console.log('data-message-id:', messageId); io.unobserve(entry.target); $.ajax({ type: 'POST', url: '{{ route('mark.message.as.read') }}', // Replace with your route data: { '_token': '{{ csrf_token() }}', 'id': messageId }, success: function(response) { if (response.senderdiv) { $('.' + response.senderdiv).find('.unread-bar-divider') .prepend(response.html); // console.log('Message marked as read successfully'); } }, error: function(error) { console.error('Failed to mark message as read'); } }); entry.target.remove(); } }); } function setupIntersectionObserver() { function reportIntersection(entries) { entries.forEach(entry => { if (entry.isIntersecting) { var messageId = entry.target.getAttribute('data-message-id'); // console.log('data-message-id:', messageId); let number = 0; const activeTab = document.querySelector('.tab-pane.show.active'); const messagePanelId = activeTab.querySelector('.message-panel').id; const match = messagePanelId.match( /\d+/); // This RegEx extracts one or more digits if (match) { const number = match[0]; // console.log(number); } io.unobserve(entry.target); $.ajax({ type: 'POST', url: '{{ route('mark.message.as.read') }}', // Replace with your route data: { '_token': '{{ csrf_token() }}', 'id': messageId, 'sender_id': document.querySelector('.tab-pane.show.active') .querySelector('.message-panel').id.match( /\d+/)[0], }, success: function(response) { if (response.senderdiv) { $('.' + response.senderdiv).find('.unread-bar-divider').prepend(response.html); $(response.countdiv).text(response.count); // console.log('Message marked as read successfully'); } }, error: function(error) { console.error('Failed to mark message as read'); } }); setTimeout(() => { entry.target.remove(); }, 100); } }); } var activeTab = document.querySelector('.tab-pane.show.active'); if (activeTab) { const container = activeTab.querySelector('.message-panel'); io = new IntersectionObserver(reportIntersection, { root: container, rootMargin: '0px', threshold: 0.5 }); activeTab.querySelectorAll('.unread-message').forEach(item => { io.observe(item); }); } } setupIntersectionObserver(); }); </script> @endsection
| ver. 1.4 |
Github
|
.
| PHP 8.1.29 | Генерация страницы: 0 |
proxy
|
phpinfo
|
Настройка