mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-06-17 02:05:22 -04:00
Let email sends continue after closing compose tab
This commit is contained in:
+67
-18
@@ -2776,6 +2776,7 @@ import * as Modals from './modalManager.js';
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function _sendEmail() {
|
async function _sendEmail() {
|
||||||
|
const sendDocId = activeDocId;
|
||||||
const to = document.getElementById('doc-email-to')?.value?.trim();
|
const to = document.getElementById('doc-email-to')?.value?.trim();
|
||||||
const cc = document.getElementById('doc-email-cc')?.value?.trim() || '';
|
const cc = document.getElementById('doc-email-cc')?.value?.trim() || '';
|
||||||
const bcc = document.getElementById('doc-email-bcc')?.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));
|
const _sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
|
||||||
let sendSpinner = null;
|
let sendSpinner = null;
|
||||||
let origBtnHtml = '';
|
let origBtnHtml = '';
|
||||||
|
let detachedEmailDoc = null;
|
||||||
if (btn) {
|
if (btn) {
|
||||||
btn.disabled = true;
|
btn.disabled = true;
|
||||||
origBtnHtml = btn.innerHTML;
|
origBtnHtml = btn.innerHTML;
|
||||||
@@ -2822,8 +2824,11 @@ import * as Modals from './modalManager.js';
|
|||||||
onAction: () => { canceled = true; },
|
onAction: () => { canceled = true; },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
detachedEmailDoc = _detachActiveEmailForBackground(sendDocId);
|
||||||
await _sleep(1200);
|
await _sleep(1200);
|
||||||
if (canceled) {
|
if (canceled) {
|
||||||
|
_restoreDetachedEmailDoc(detachedEmailDoc);
|
||||||
|
detachedEmailDoc = null;
|
||||||
if (uiModule) uiModule.showToast('Send canceled');
|
if (uiModule) uiModule.showToast('Send canceled');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2839,6 +2844,8 @@ import * as Modals from './modalManager.js';
|
|||||||
}
|
}
|
||||||
await _sleep(2200);
|
await _sleep(2200);
|
||||||
if (undone) {
|
if (undone) {
|
||||||
|
_restoreDetachedEmailDoc(detachedEmailDoc);
|
||||||
|
detachedEmailDoc = null;
|
||||||
if (uiModule) uiModule.showToast('Send undone');
|
if (uiModule) uiModule.showToast('Send undone');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2858,15 +2865,6 @@ import * as Modals from './modalManager.js';
|
|||||||
});
|
});
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
if (data.success) {
|
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) {
|
if (uiModule) {
|
||||||
uiModule.showToast('Message sent', {
|
uiModule.showToast('Message sent', {
|
||||||
duration: 7000,
|
duration: 7000,
|
||||||
@@ -2908,22 +2906,31 @@ import * as Modals from './modalManager.js';
|
|||||||
// Tell the inbox to refresh so the answered state shows
|
// Tell the inbox to refresh so the answered state shows
|
||||||
window.dispatchEvent(new CustomEvent('email-answered', { detail: { uid: sourceUid } }));
|
window.dispatchEvent(new CustomEvent('email-answered', { detail: { uid: sourceUid } }));
|
||||||
}
|
}
|
||||||
// Delete the document after successful send
|
// Delete the compose document after successful send. It was usually
|
||||||
if (activeDocId) {
|
// already detached from the visible tabs so sending can finish in the
|
||||||
fetch(`${API_BASE}/api/document/${activeDocId}`, { method: 'DELETE' }).catch(() => {});
|
// background while the user continues in the next tab.
|
||||||
docs.delete(activeDocId);
|
if (sendDocId) {
|
||||||
const remaining = Array.from(docs.keys());
|
fetch(`${API_BASE}/api/document/${sendDocId}`, { method: 'DELETE' }).catch(() => {});
|
||||||
if (remaining.length > 0) {
|
const wasActiveSentDoc = activeDocId === sendDocId;
|
||||||
switchToDoc(remaining[0]);
|
docs.delete(sendDocId);
|
||||||
|
if (wasActiveSentDoc) {
|
||||||
|
activeDocId = null;
|
||||||
|
const nextId = _visibleDocIdsForCurrentSession().find(id => docs.has(id));
|
||||||
|
if (nextId) switchToDoc(nextId);
|
||||||
|
else closePanel();
|
||||||
} else {
|
} else {
|
||||||
closePanel();
|
renderTabs();
|
||||||
}
|
}
|
||||||
renderTabs();
|
_syncDocIndicator();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
_restoreDetachedEmailDoc(detachedEmailDoc);
|
||||||
|
detachedEmailDoc = null;
|
||||||
if (uiModule) uiModule.showError(data.error || 'Failed to send');
|
if (uiModule) uiModule.showError(data.error || 'Failed to send');
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
_restoreDetachedEmailDoc(detachedEmailDoc);
|
||||||
|
detachedEmailDoc = null;
|
||||||
if (uiModule) uiModule.showError(e?.message ? `Failed to send email: ${e.message}` : 'Failed to send email');
|
if (uiModule) uiModule.showError(e?.message ? `Failed to send email: ${e.message}` : 'Failed to send email');
|
||||||
} finally {
|
} finally {
|
||||||
if (sendSpinner) sendSpinner.destroy();
|
if (sendSpinner) sendSpinner.destroy();
|
||||||
@@ -2986,6 +2993,48 @@ import * as Modals from './modalManager.js';
|
|||||||
_closeWithoutDeleting(true);
|
_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) {
|
function _closeWithoutDeleting(deleteDoc = false) {
|
||||||
if (!activeDocId) return;
|
if (!activeDocId) return;
|
||||||
if (deleteDoc) {
|
if (deleteDoc) {
|
||||||
|
|||||||
Reference in New Issue
Block a user