').addClass('text-muted small').text('Empresa informe'))
);
});
if (!hasCompanies) {
$container.append($('').addClass('text-muted').text('Sin empresas vinculadas'));
}
}
function chatSemanticLabelColor(badge) {
var colors = {
warning: 'yellow',
info: 'blue',
success: 'green',
danger: 'red',
secondary: 'grey',
primary: 'blue',
dark: 'grey',
light: 'grey basic'
};
return colors[badge] || 'grey';
}
function updateConversationHeader(chat) {
if (!chat) {
return;
}
setActiveChatId(chat.id_portal_chat_conversacion);
$('#chat-admin-active-subject').text(chat.asunto_mostrar || '');
$('#chat-admin-active-client').text(chat.cliente_portal || '');
$('#chat-admin-active-email').text(chat.correo_portal || '');
renderConversationCompanies(chat);
$('#chat-admin-active-status')
.attr('class', 'ui ' + chatSemanticLabelColor(chat.estado_badge || 'primary') + ' label')
.text(chat.estado_mostrar || 'Asignado');
}
function updateSidebar(html) {
if (typeof html === 'string') {
$('#chat-admin-sidebar-body').html(html);
}
}
function updateReplyAvailability(canReply) {
if (canReply) {
$('#chat-admin-composer-wrap').removeClass('d-none');
$('#chat-admin-closed-alert').addClass('d-none');
return;
}
$('#chat-admin-composer-wrap').addClass('d-none');
$('#chat-admin-closed-alert').removeClass('d-none');
}
function isHistoryNearBottom() {
var $history = $('#chat-admin-history');
if (!$history.length) {
return false;
}
var element = $history.get(0);
return (element.scrollHeight - element.scrollTop - $history.outerHeight()) < 120;
}
function scrollHistoryToBottom() {
var $history = $('#chat-admin-history');
if (!$history.length) {
return;
}
$history.scrollTop($history.get(0).scrollHeight);
}
function removeHistoryEmptyState() {
$('#chat-admin-history-empty').remove();
}
function getRenderedLastMessageId() {
var $lastMessage = $('#chat-admin-history').find('.chat-message-row').last();
if (!$lastMessage.length) {
return 0;
}
return parseInt($lastMessage.attr('data-message-id'), 10) || 0;
}
function sortHistoryRows() {
var $thread = $('#chat-admin-thread');
if (!$thread.length) {
return;
}
var rows = $thread.children('.chat-message-row').get();
rows.sort(function(left, right) {
var leftId = parseInt($(left).attr('data-message-id'), 10) || 0;
var rightId = parseInt($(right).attr('data-message-id'), 10) || 0;
return leftId - rightId;
});
$.each(rows, function(index, row) {
$thread.append(row);
});
}
function replaceHistoryHtml(html, shouldScroll, shouldPlaySound, fallbackLastMessageId) {
$('#chat-admin-history').html(html);
sortHistoryRows();
setHistoryLastMessageId(getRenderedLastMessageId() || fallbackLastMessageId || 0);
if (shouldScroll) {
scrollHistoryToBottom();
}
if (shouldPlaySound) {
playIncomingSound();
}
}
function reloadConversationHistory(chatId, shouldScroll, shouldPlaySound, fallbackLastMessageId) {
if (!chatId) {
return $.Deferred().resolve().promise();
}
historyRefreshInFlight = true;
return $.ajax({
url: buildMessagesUrl(chatId),
type: 'GET',
dataType: 'html',
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
}).done(function(html) {
replaceHistoryHtml(html, shouldScroll, shouldPlaySound, fallbackLastMessageId);
}).fail(function(xhr) {
if (xhr && (xhr.status === 403 || xhr.status === 404)) {
window.location.href = $chatRoot.data('index-url');
}
}).always(function() {
historyRefreshInFlight = false;
});
}
function playIncomingSound() {
try {
var AudioCtx = window.AudioContext || window.webkitAudioContext;
if (!AudioCtx) {
return;
}
if (!audioContext) {
audioContext = new AudioCtx();
}
if (audioContext.state === 'suspended') {
audioContext.resume();
}
var oscillator = audioContext.createOscillator();
var gainNode = audioContext.createGain();
oscillator.type = 'sine';
oscillator.frequency.setValueAtTime(880, audioContext.currentTime);
gainNode.gain.setValueAtTime(0.001, audioContext.currentTime);
gainNode.gain.exponentialRampToValueAtTime(0.08, audioContext.currentTime + 0.01);
gainNode.gain.exponentialRampToValueAtTime(0.001, audioContext.currentTime + 0.18);
oscillator.connect(gainNode);
gainNode.connect(audioContext.destination);
oscillator.start();
oscillator.stop(audioContext.currentTime + 0.18);
} catch (error) {
console.log('No fue posible reproducir el sonido del chat.', error);
}
}
function resetSelectedFile() {
$('#chat-admin-selected-file').addClass('d-none').text('');
}
function updateSelectedFile() {
var input = $('#chat-admin-file-input').get(0);
if (!input || !input.files || !input.files.length) {
resetSelectedFile();
return;
}
$('#chat-admin-selected-file')
.removeClass('d-none')
.text('Archivo seleccionado: ' + input.files[0].name);
}
function resolveErrorMessage(xhr) {
if (!xhr || !xhr.responseJSON) {
return 'No fue posible completar la operación.';
}
if (xhr.responseJSON.message) {
return xhr.responseJSON.message;
}
if (xhr.responseJSON.errors) {
var firstKey = Object.keys(xhr.responseJSON.errors)[0];
if (firstKey && xhr.responseJSON.errors[firstKey].length) {
return xhr.responseJSON.errors[firstKey][0];
}
}
return 'No fue posible completar la operación.';
}
function shouldPollChat() {
return getActiveChatId() > 0 && $('#tab-mis-chats').hasClass('active');
}
function scheduleChatPoll() {
clearTimeout(pollTimer);
if (!shouldPollChat()) {
return;
}
pollTimer = setTimeout(function() {
runChatPoll();
}, pollInterval);
}
function runChatPoll() {
if (pollInFlight || historyRefreshInFlight || !shouldPollChat()) {
scheduleChatPoll();
return;
}
pollInFlight = true;
var nearBottom = isHistoryNearBottom();
var currentLastMessageId = getHistoryLastMessageId();
$.ajax({
url: buildPollUrl(getActiveChatId()),
type: 'GET',
dataType: 'json',
data: {
ultimo_id_mensaje: currentLastMessageId
},
success: function(response) {
if (response.chat_activo) {
updateConversationHeader(response.chat_activo);
}
updateSidebar(response.mis_chats_html);
updateReplyAvailability(response.puede_responder);
var ultimoIdMensaje = parseInt(response.ultimo_id_mensaje, 10) || 0;
var hayMensajesNuevos = !!response.hay_mensajes_nuevos || ultimoIdMensaje > currentLastMessageId;
if (response.hay_mensajes_cliente_nuevos && typeof refreshSystemNotifications === 'function') {
refreshSystemNotifications();
}
if (!hayMensajesNuevos) {
setHistoryLastMessageId(ultimoIdMensaje);
return;
}
reloadConversationHistory(
getActiveChatId(),
nearBottom,
!!response.hay_mensajes_cliente_nuevos,
ultimoIdMensaje
);
},
error: function(xhr) {
if (xhr.status === 403 || xhr.status === 404) {
window.location.href = $chatRoot.data('index-url');
}
},
complete: function() {
pollInFlight = false;
scheduleChatPoll();
}
});
}
$(document).on('click', '#chat-admin-finalize-button', function(event) {
event.preventDefault();
var $form = $('#chat-admin-finalize-form');
showConfirmModal(
'¿Deseas finalizar esta conversación? Después de finalizarla ya no podrán enviarse nuevos mensajes.',
'Confirmación',
'Finalizar'
).then(function(confirmado) {
if (!confirmado || !$form.length) {
return;
}
$form[0].submit();
});
});
$('#chat-admin-file-input').on('change', function() {
updateSelectedFile();
});
$('#chat-admin-message-input').on('input', function() {
updateTextareaHeight();
});
$('#chat-admin-reply-form').on('submit', function(event) {
event.preventDefault();
if (sendInFlight) {
return;
}
var $form = $(this);
var messageValue = $.trim($('#chat-admin-message-input').val());
var fileInput = $('#chat-admin-file-input').get(0);
var hasFile = fileInput && fileInput.files && fileInput.files.length > 0;
if (messageValue === '' && !hasFile) {
showFeedback('danger', 'Captura un mensaje o adjunta un archivo.');
return;
}
hideFeedback();
sendInFlight = true;
$('#chat-admin-send-button').addClass('loading disabled');
$.ajax({
url: $form.attr('action'),
type: 'POST',
data: new FormData($form.get(0)),
processData: false,
contentType: false,
headers: {
'X-Requested-With': 'XMLHttpRequest'
},
success: function(response) {
showFeedback('success', response.message || 'Mensaje enviado correctamente.');
if (response.chat_activo) {
updateConversationHeader(response.chat_activo);
}
if (response.mis_chats_html) {
updateSidebar(response.mis_chats_html);
}
if (typeof refreshSystemNotifications === 'function') {
refreshSystemNotifications();
}
updateReplyAvailability(response.puede_responder);
$('#chat-admin-message-input').val('');
$('#chat-admin-file-input').val('');
resetSelectedFile();
updateTextareaHeight();
if (typeof response.historial_html === 'string') {
replaceHistoryHtml(response.historial_html, true, false, response.ultimo_id_mensaje);
} else {
reloadConversationHistory(getActiveChatId(), true, false, response.ultimo_id_mensaje);
}
},
error: function(xhr) {
showFeedback('danger', resolveErrorMessage(xhr));
},
complete: function() {
sendInFlight = false;
$('#chat-admin-send-button').removeClass('loading disabled');
scheduleChatPoll();
}
});
});
$('a[data-toggle="tab"]').on('shown.bs.tab', function(event) {
var target = $(event.target).attr('href');
if (target === '#tab-mis-chats') {
scrollHistoryToBottom();
scheduleChatPoll();
return;
}
clearTimeout(pollTimer);
});
updateTextareaHeight();
updateSelectedFile();
sortHistoryRows();
if ($('#tab-mis-chats').hasClass('active')) {
scrollHistoryToBottom();
scheduleChatPoll();
}
}
@endsection