Update conversations.php
This commit is contained in:
+85
-1
@@ -940,6 +940,9 @@
|
||||
// Track whether the user is actively scrolling/reading to avoid forcing scroll-to-bottom
|
||||
this._userScrolling = false;
|
||||
this._userScrollTimer = null;
|
||||
// Suspend periodic refresh while media playback or recording is active
|
||||
this._suspendAutoRefresh = false;
|
||||
this._pendingReloadAfterMedia = false;
|
||||
// Removed: automatic "Nuevos mensajes" indicator — we always reload full conversation now
|
||||
// this._lastRenderMessageCount = 0;
|
||||
|
||||
@@ -1535,9 +1538,17 @@
|
||||
}, 30000);
|
||||
|
||||
// Actualizar mensajes del chat activo cada 10 segundos
|
||||
// Use full reload (initial=true) — always fetch the full conversation and scroll to bottom
|
||||
// Use full reload (initial=true) — always fetch the full conversation and scroll to bottom,
|
||||
// but suspend while media playback or recording is active (to avoid interrupting)
|
||||
setInterval(() => {
|
||||
if (this.currentUserId) {
|
||||
try {
|
||||
if (typeof this.isMediaActive === 'function' && this.isMediaActive()) {
|
||||
console.debug('Periodic load skipped: media active or recording in progress; scheduling reload after media ends');
|
||||
this._pendingReloadAfterMedia = true;
|
||||
return;
|
||||
}
|
||||
} catch (e) { console.warn('isMediaActive check failed', e); }
|
||||
// full reload forces scroll-to-bottom
|
||||
this.loadMessages(this.currentUserId, true).catch(err => console.warn('Periodic loadMessages failed', err));
|
||||
}
|
||||
@@ -2023,6 +2034,30 @@
|
||||
});
|
||||
chatContainer._infiniteScrollAdded = true;
|
||||
}
|
||||
|
||||
// Media playback listeners: suspend auto-refresh while media is playing and resume when it stops
|
||||
if (!chatContainer._mediaListenersAdded) {
|
||||
const onMediaPlay = (ev) => {
|
||||
try {
|
||||
this._suspendAutoRefresh = true;
|
||||
console.debug('Media play detected, suspending periodic reload');
|
||||
} catch (e) { /* ignore */ }
|
||||
};
|
||||
const onMediaEnd = async (ev) => {
|
||||
try {
|
||||
this._suspendAutoRefresh = false;
|
||||
console.debug('Media paused/ended, resuming periodic reload');
|
||||
if (this._pendingReloadAfterMedia && this.currentUserId) {
|
||||
this._pendingReloadAfterMedia = false;
|
||||
await this.loadMessages(this.currentUserId, true);
|
||||
}
|
||||
} catch (e) { console.warn('media end handler failed', e); }
|
||||
};
|
||||
chatContainer.addEventListener('play', onMediaPlay, true);
|
||||
chatContainer.addEventListener('pause', onMediaEnd, true);
|
||||
chatContainer.addEventListener('ended', onMediaEnd, true);
|
||||
chatContainer._mediaListenersAdded = true;
|
||||
}
|
||||
}
|
||||
// Cargar respuestas rápidas y plantillas
|
||||
await this.loadQuickReplies();
|
||||
@@ -2588,6 +2623,26 @@
|
||||
return !(hasContent || hasMedia || nonText);
|
||||
}
|
||||
|
||||
// Helper: detect active media playback or recording to avoid interrupting with reloads
|
||||
isMediaActive() {
|
||||
// Recording in progress -> active
|
||||
if (this._mediaRecorder && this._mediaRecorder.state === 'recording') return true;
|
||||
// Explicit suspend flag
|
||||
if (this._suspendAutoRefresh) return true;
|
||||
try {
|
||||
const container = document.getElementById('chat-conversations');
|
||||
if (!container) return false;
|
||||
const mediaEls = container.querySelectorAll('audio,video');
|
||||
for (const el of mediaEls) {
|
||||
if (!el.paused && !el.ended) return true;
|
||||
if (el.readyState > 2 && !el.paused) return true;
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('isMediaActive: failed to inspect media elements', e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Initialize recording handlers (so mic works before openConversation) and helper to manage recording state
|
||||
initRecordingHandlers() {
|
||||
if (this._recordingHandlersInitialized) return;
|
||||
@@ -2598,6 +2653,8 @@
|
||||
|
||||
this.startRecording = async function() {
|
||||
try {
|
||||
// Suspend periodic reload while recording
|
||||
this._suspendAutoRefresh = true;
|
||||
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
||||
this._mediaRecorder = new MediaRecorder(stream);
|
||||
const chunks = [];
|
||||
@@ -2628,6 +2685,15 @@
|
||||
} catch(e) { /* ignore */ }
|
||||
// Clear recorder reference to indicate stopped
|
||||
this._mediaRecorder = null;
|
||||
|
||||
// Resume auto-refresh and trigger a reload if one was pending
|
||||
try {
|
||||
this._suspendAutoRefresh = false;
|
||||
if (this._pendingReloadAfterMedia && this.currentUserId) {
|
||||
this._pendingReloadAfterMedia = false;
|
||||
await this.loadMessages(this.currentUserId, true);
|
||||
}
|
||||
} catch (e) { console.warn('Failed to resume reload after recording', e); }
|
||||
};
|
||||
|
||||
this._mediaRecorder.start();
|
||||
@@ -2667,6 +2733,15 @@
|
||||
const ind = document.getElementById('recording-indicator'); if (ind) ind.style.display = 'none';
|
||||
const micEl = document.getElementById('mic-btn'); if (micEl) micEl.classList.remove('recording');
|
||||
if (this._updateSendMicVisibility) this._updateSendMicVisibility();
|
||||
|
||||
// Ensure we resume periodic reloads and trigger pending reload
|
||||
try {
|
||||
this._suspendAutoRefresh = false;
|
||||
if (this._pendingReloadAfterMedia && this.currentUserId) {
|
||||
this._pendingReloadAfterMedia = false;
|
||||
this.loadMessages(this.currentUserId, true).catch(e => console.warn('Reload after stopRecording failed', e));
|
||||
}
|
||||
} catch (e) { console.warn('stopRecording resume failed', e); }
|
||||
};
|
||||
|
||||
this.cancelRecording = function() {
|
||||
@@ -2688,6 +2763,15 @@
|
||||
// hide delete button if present
|
||||
const delBtn = document.getElementById('delete-file-btn'); if (delBtn) delBtn.style.display = 'none';
|
||||
if (this._updateSendMicVisibility) this._updateSendMicVisibility();
|
||||
|
||||
// Resume auto-refresh if it was suspended and trigger pending reload
|
||||
try {
|
||||
this._suspendAutoRefresh = false;
|
||||
if (this._pendingReloadAfterMedia && this.currentUserId) {
|
||||
this._pendingReloadAfterMedia = false;
|
||||
this.loadMessages(this.currentUserId, true).catch(e => console.warn('Reload after cancelRecording failed', e));
|
||||
}
|
||||
} catch (e) { console.warn('cancelRecording resume failed', e); }
|
||||
};
|
||||
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user