up
This commit is contained in:
+89
-17
@@ -1764,6 +1764,38 @@
|
||||
return text.substring(0, maxLength) + '...';
|
||||
}
|
||||
|
||||
// Cache ligero del estado del usuario (in_service, advisor_requested, on_hold)
|
||||
async getUserState(userId, force = false) {
|
||||
if (!userId) return null;
|
||||
this._userStateCache = this._userStateCache || {};
|
||||
const now = Date.now();
|
||||
const cached = this._userStateCache[userId];
|
||||
const TTL = 15000; // 15 segundos
|
||||
if (!force && cached && (now - cached.ts) < TTL) {
|
||||
return cached.state;
|
||||
}
|
||||
|
||||
try {
|
||||
const resp = await this.apiCall(`get_conversation_detail.php?user_id=${userId}`);
|
||||
if (resp && resp.success && resp.user) {
|
||||
const s = {
|
||||
in_service: !!resp.user.in_service,
|
||||
advisor_requested: !!resp.user.advisor_requested,
|
||||
on_hold: !!resp.user.on_hold
|
||||
};
|
||||
this._userStateCache[userId] = { state: s, ts: Date.now() };
|
||||
return s;
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('getUserState failed for', userId, e);
|
||||
}
|
||||
|
||||
// fallback: keep previous cached or return null
|
||||
if (cached) return cached.state;
|
||||
this._userStateCache[userId] = { state: null, ts: Date.now() };
|
||||
return null;
|
||||
}
|
||||
|
||||
getConversationPhone(userId) {
|
||||
const conv = this.conversations.find(c => c.user_id === userId);
|
||||
if (conv) return conv.phone_number || conv.phone || conv.user_phone || null;
|
||||
@@ -1911,28 +1943,57 @@
|
||||
// refresh conv reference
|
||||
const c = this.conversations.find(x => x.user_id === userId) || conv;
|
||||
|
||||
if (c.in_service) {
|
||||
attendToggleBtn.innerHTML = '<i class="fas fa-user-times"></i> Finalizar';
|
||||
attendToggleBtn.classList.remove('btn-outline-light');
|
||||
attendToggleBtn.classList.add('btn-light','text-dark');
|
||||
attendToggleBtn.style.display = 'inline-block';
|
||||
attendStatus.textContent = `Atendido por ${c.in_service_by_name || 'un asesor'}`;
|
||||
} else if (c.advisor_requested) {
|
||||
attendToggleBtn.innerHTML = '<i class="fas fa-user-check"></i> Atender';
|
||||
attendToggleBtn.classList.remove('btn-light','text-dark');
|
||||
attendToggleBtn.classList.add('btn-outline-light');
|
||||
attendToggleBtn.style.display = 'inline-block';
|
||||
attendStatus.textContent = '';
|
||||
} else {
|
||||
attendToggleBtn.style.display = 'none';
|
||||
attendStatus.textContent = '';
|
||||
}
|
||||
// request a cached state (fast) to be more preciso
|
||||
this.getUserState(userId).then(serverState => {
|
||||
const s = serverState || { in_service: c.in_service, advisor_requested: c.advisor_requested };
|
||||
|
||||
if (s.in_service) {
|
||||
attendToggleBtn.innerHTML = '<i class="fas fa-user-times"></i> Finalizar';
|
||||
attendToggleBtn.classList.remove('btn-outline-light');
|
||||
attendToggleBtn.classList.add('btn-light','text-dark');
|
||||
attendToggleBtn.style.display = 'inline-block';
|
||||
attendStatus.textContent = `Atendido por ${c.in_service_by_name || 'un asesor'}`;
|
||||
} else if (s.advisor_requested) {
|
||||
attendToggleBtn.innerHTML = '<i class="fas fa-user-check"></i> Atender';
|
||||
attendToggleBtn.classList.remove('btn-light','text-dark');
|
||||
attendToggleBtn.classList.add('btn-outline-light');
|
||||
attendToggleBtn.style.display = 'inline-block';
|
||||
attendStatus.textContent = '';
|
||||
} else {
|
||||
attendToggleBtn.style.display = 'none';
|
||||
attendStatus.textContent = '';
|
||||
}
|
||||
}).catch(e => {
|
||||
// fallback to local conv fields
|
||||
if (c.in_service) {
|
||||
attendToggleBtn.innerHTML = '<i class="fas fa-user-times"></i> Finalizar';
|
||||
attendToggleBtn.classList.remove('btn-outline-light');
|
||||
attendToggleBtn.classList.add('btn-light','text-dark');
|
||||
attendToggleBtn.style.display = 'inline-block';
|
||||
attendStatus.textContent = `Atendido por ${c.in_service_by_name || 'un asesor'}`;
|
||||
} else if (c.advisor_requested) {
|
||||
attendToggleBtn.innerHTML = '<i class="fas fa-user-check"></i> Atender';
|
||||
attendToggleBtn.classList.remove('btn-light','text-dark');
|
||||
attendToggleBtn.classList.add('btn-outline-light');
|
||||
attendToggleBtn.style.display = 'inline-block';
|
||||
attendStatus.textContent = '';
|
||||
} else {
|
||||
attendToggleBtn.style.display = 'none';
|
||||
attendStatus.textContent = '';
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const toggleAttend = async () => {
|
||||
try {
|
||||
const c = this.conversations.find(x => x.user_id === userId) || conv;
|
||||
if (c.in_service) {
|
||||
|
||||
// Preflight: obtener estado canonico del servidor con cache corta
|
||||
const serverState = await this.getUserState(userId, true);
|
||||
const currentlyInService = serverState ? !!serverState.in_service : !!c.in_service;
|
||||
|
||||
if (currentlyInService) {
|
||||
if (!confirm('¿Confirmas finalizar la atención?')) return;
|
||||
const resp = await this.apiCall('finish_attend.php', { body: { user_id: userId } });
|
||||
if (resp && resp.success) {
|
||||
showAlert('Finalizada la atención', 'success');
|
||||
@@ -1940,12 +2001,18 @@
|
||||
c.advisor_requested = 0;
|
||||
// hide hold indicator
|
||||
if (holdIndicator) holdIndicator.style.display = 'none';
|
||||
|
||||
// actualizar cache local
|
||||
this._userStateCache = this._userStateCache || {};
|
||||
this._userStateCache[userId] = { state: { in_service: false, advisor_requested: false, on_hold: false }, ts: Date.now() };
|
||||
|
||||
await this.loadConversations();
|
||||
await this.loadMessages(userId, true);
|
||||
} else {
|
||||
throw new Error(resp && resp.error ? resp.error : 'Error finalizando');
|
||||
}
|
||||
} else {
|
||||
if (!confirm('¿Confirmas tomar la atención de esta conversación?')) return;
|
||||
const resp = await this.apiCall('attend.php', { body: { user_id: userId } });
|
||||
if (resp && resp.success) {
|
||||
showAlert('Atención iniciada', 'success');
|
||||
@@ -1958,6 +2025,11 @@
|
||||
}
|
||||
// hide bot toggle while in service
|
||||
if (btn) btn.style.display = 'none';
|
||||
|
||||
// actualizar cache local
|
||||
this._userStateCache = this._userStateCache || {};
|
||||
this._userStateCache[userId] = { state: { in_service: true, advisor_requested: false, on_hold: false }, ts: Date.now() };
|
||||
|
||||
await this.loadConversations();
|
||||
await this.loadMessages(userId, true);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user