Let email sends continue after closing compose tab
This commit is contained in:
@@ -2776,6 +2776,7 @@ import * as Modals from './modalManager.js';
|
||||
}
|
||||
|
||||
async function _sendEmail() {
|
||||
const sendDocId = activeDocId;
|
||||
const to = document.getElementById('doc-email-to')?.value?.trim();
|
||||
const cc = document.getElementById('doc-email-cc')?.value?.trim() || '';
|
||||
const bcc = document.getElementById('doc-email-bcc')?.value?.trim() || '';
|
||||
@@ -2804,6 +2805,7 @@ import * as Modals from './modalManager.js';
|
||||
const _sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
|
||||
let sendSpinner = null;
|
||||
let origBtnHtml = '';
|
||||
let detachedEmailDoc = null;
|
||||
if (btn) {
|
||||
btn.disabled = true;
|
||||
origBtnHtml = btn.innerHTML;
|
||||
@@ -2822,8 +2824,11 @@ import * as Modals from './modalManager.js';
|
||||
onAction: () => { canceled = true; },
|
||||
});
|
||||
}
|
||||
detachedEmailDoc = _detachActiveEmailForBackground(sendDocId);
|
||||
await _sleep(1200);
|
||||
if (canceled) {
|
||||
_restoreDetachedEmailDoc(detachedEmailDoc);
|
||||
detachedEmailDoc = null;
|
||||
if (uiModule) uiModule.showToast('Send canceled');
|
||||
return;
|
||||
}
|
||||
@@ -2839,6 +2844,8 @@ import * as Modals from './modalManager.js';
|
||||
}
|
||||
await _sleep(2200);
|
||||
if (undone) {
|
||||
_restoreDetachedEmailDoc(detachedEmailDoc);
|
||||
detachedEmailDoc = null;
|
||||
if (uiModule) uiModule.showToast('Send undone');
|
||||
return;
|
||||
}
|
||||
@@ -2858,15 +2865,6 @@ import * as Modals from './modalManager.js';
|
||||
});
|
||||
const data = await res.json();
|
||||
if (data.success) {
|
||||
// Satisfying send effect: fly the email doc upward with fade
|
||||
const docPane = document.getElementById('doc-pane') || document.querySelector('.doc-pane');
|
||||
const emailHeader = document.getElementById('doc-email-header');
|
||||
const editorWrap = document.getElementById('doc-editor-wrap');
|
||||
const target = emailHeader?.parentElement || docPane;
|
||||
if (target) {
|
||||
target.classList.add('email-send-fx');
|
||||
setTimeout(() => target.classList.remove('email-send-fx'), 700);
|
||||
}
|
||||
if (uiModule) {
|
||||
uiModule.showToast('Message sent', {
|
||||
duration: 7000,
|
||||
@@ -2908,22 +2906,31 @@ import * as Modals from './modalManager.js';
|
||||
// Tell the inbox to refresh so the answered state shows
|
||||
window.dispatchEvent(new CustomEvent('email-answered', { detail: { uid: sourceUid } }));
|
||||
}
|
||||
// Delete the document after successful send
|
||||
if (activeDocId) {
|
||||
fetch(`${API_BASE}/api/document/${activeDocId}`, { method: 'DELETE' }).catch(() => {});
|
||||
docs.delete(activeDocId);
|
||||
const remaining = Array.from(docs.keys());
|
||||
if (remaining.length > 0) {
|
||||
switchToDoc(remaining[0]);
|
||||
// Delete the compose document after successful send. It was usually
|
||||
// already detached from the visible tabs so sending can finish in the
|
||||
// background while the user continues in the next tab.
|
||||
if (sendDocId) {
|
||||
fetch(`${API_BASE}/api/document/${sendDocId}`, { method: 'DELETE' }).catch(() => {});
|
||||
const wasActiveSentDoc = activeDocId === sendDocId;
|
||||
docs.delete(sendDocId);
|
||||
if (wasActiveSentDoc) {
|
||||
activeDocId = null;
|
||||
const nextId = _visibleDocIdsForCurrentSession().find(id => docs.has(id));
|
||||
if (nextId) switchToDoc(nextId);
|
||||
else closePanel();
|
||||
} else {
|
||||
closePanel();
|
||||
renderTabs();
|
||||
}
|
||||
renderTabs();
|
||||
_syncDocIndicator();
|
||||
}
|
||||
} else {
|
||||
_restoreDetachedEmailDoc(detachedEmailDoc);
|
||||
detachedEmailDoc = null;
|
||||
if (uiModule) uiModule.showError(data.error || 'Failed to send');
|
||||
}
|
||||
} catch (e) {
|
||||
_restoreDetachedEmailDoc(detachedEmailDoc);
|
||||
detachedEmailDoc = null;
|
||||
if (uiModule) uiModule.showError(e?.message ? `Failed to send email: ${e.message}` : 'Failed to send email');
|
||||
} finally {
|
||||
if (sendSpinner) sendSpinner.destroy();
|
||||
@@ -2986,6 +2993,48 @@ import * as Modals from './modalManager.js';
|
||||
_closeWithoutDeleting(true);
|
||||
}
|
||||
|
||||
function _visibleDocIdsForCurrentSession() {
|
||||
const curSession = sessionModule?.getCurrentSessionId() || '';
|
||||
const ids = [];
|
||||
for (const [id, doc] of docs) {
|
||||
if (doc.sessionId && curSession && doc.sessionId !== curSession) continue;
|
||||
ids.push(id);
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
function _detachActiveEmailForBackground(docId) {
|
||||
if (!docId || !docs.has(docId)) return null;
|
||||
saveCurrentToMap();
|
||||
const doc = docs.get(docId);
|
||||
const snapshot = { id: docId, doc: { ...doc } };
|
||||
saveDocument({ silent: true }).catch(() => {});
|
||||
|
||||
const visibleBefore = _visibleDocIdsForCurrentSession();
|
||||
const idx = visibleBefore.indexOf(docId);
|
||||
docs.delete(docId);
|
||||
if (activeDocId === docId) activeDocId = null;
|
||||
|
||||
const remaining = visibleBefore.filter(id => id !== docId && docs.has(id));
|
||||
const nextId = remaining[idx] || remaining[idx - 1] || remaining[0] || null;
|
||||
if (nextId) {
|
||||
switchToDoc(nextId);
|
||||
} else {
|
||||
closePanel();
|
||||
}
|
||||
renderTabs();
|
||||
_syncDocIndicator();
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
function _restoreDetachedEmailDoc(snapshot) {
|
||||
if (!snapshot || !snapshot.id || !snapshot.doc) return;
|
||||
if (!docs.has(snapshot.id)) docs.set(snapshot.id, snapshot.doc);
|
||||
_ensureDocPaneMounted();
|
||||
switchToDoc(snapshot.id);
|
||||
_syncDocIndicator();
|
||||
}
|
||||
|
||||
function _closeWithoutDeleting(deleteDoc = false) {
|
||||
if (!activeDocId) return;
|
||||
if (deleteDoc) {
|
||||
|
||||
Reference in New Issue
Block a user