mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-07-08 11:56:59 +00:00
Show busy spinner while deleting email
This commit is contained in:
@@ -1183,15 +1183,42 @@ async function _deleteEmail(em) {
|
|||||||
const { styledConfirm } = await import('./ui.js');
|
const { styledConfirm } = await import('./ui.js');
|
||||||
const ok = await styledConfirm(`Delete "${subject}"?`, { confirmText: 'Delete', cancelText: 'Cancel', danger: true });
|
const ok = await styledConfirm(`Delete "${subject}"?`, { confirmText: 'Delete', cancelText: 'Cancel', danger: true });
|
||||||
if (!ok) return;
|
if (!ok) return;
|
||||||
|
const row = document.querySelector(`.email-item[data-uid="${CSS.escape(String(em.uid))}"]`);
|
||||||
|
const busy = _showEmailDeleteOverlay(row);
|
||||||
try {
|
try {
|
||||||
await fetch(`${API_BASE}/api/email/delete/${em.uid}?folder=${encodeURIComponent(_currentFolder)}${_acct()}`, { method: 'DELETE' });
|
await fetch(`${API_BASE}/api/email/delete/${em.uid}?folder=${encodeURIComponent(_currentFolder)}${_acct()}`, { method: 'DELETE' });
|
||||||
|
busy?.remove?.();
|
||||||
_emails = _emails.filter(e => e.uid !== em.uid);
|
_emails = _emails.filter(e => e.uid !== em.uid);
|
||||||
_renderList();
|
_renderList();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
busy?.remove?.();
|
||||||
console.error('Failed to delete:', e);
|
console.error('Failed to delete:', e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _showEmailDeleteOverlay(target) {
|
||||||
|
if (!target) return null;
|
||||||
|
const wp = spinnerModule.createWhirlpool(16);
|
||||||
|
const overlay = document.createElement('div');
|
||||||
|
overlay.className = 'email-delete-overlay';
|
||||||
|
overlay.appendChild(wp.element);
|
||||||
|
const prevPos = target.style.position;
|
||||||
|
const prevPointerEvents = target.style.pointerEvents;
|
||||||
|
if (getComputedStyle(target).position === 'static') target.style.position = 'relative';
|
||||||
|
target.style.pointerEvents = 'none';
|
||||||
|
target.classList.add('email-delete-busy');
|
||||||
|
target.appendChild(overlay);
|
||||||
|
return {
|
||||||
|
remove() {
|
||||||
|
try { wp.destroy?.(); } catch (_) {}
|
||||||
|
overlay.remove();
|
||||||
|
target.classList.remove('email-delete-busy');
|
||||||
|
target.style.pointerEvents = prevPointerEvents;
|
||||||
|
target.style.position = prevPos;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
async function _toggleDone(em, itemEl) {
|
async function _toggleDone(em, itemEl) {
|
||||||
const newState = !em.is_answered;
|
const newState = !em.is_answered;
|
||||||
em.is_answered = newState;
|
em.is_answered = newState;
|
||||||
|
|||||||
@@ -721,6 +721,7 @@ async function _deleteEmailAndAdvance(em, card, opts = {}) {
|
|||||||
const ok = await styledConfirm(`Delete "${subject}"?`, { confirmText: 'Delete', cancelText: 'Cancel', danger: true });
|
const ok = await styledConfirm(`Delete "${subject}"?`, { confirmText: 'Delete', cancelText: 'Cancel', danger: true });
|
||||||
if (!ok) return;
|
if (!ok) return;
|
||||||
}
|
}
|
||||||
|
const busy = _showEmailDeleteOverlay(card);
|
||||||
const wasExpanded = !!card?.classList?.contains('doclib-card-expanded');
|
const wasExpanded = !!card?.classList?.contains('doclib-card-expanded');
|
||||||
const sibling = wasExpanded
|
const sibling = wasExpanded
|
||||||
? (_findSiblingEmailCard(card, +1) || _findSiblingEmailCard(card, -1))
|
? (_findSiblingEmailCard(card, +1) || _findSiblingEmailCard(card, -1))
|
||||||
@@ -730,9 +731,11 @@ async function _deleteEmailAndAdvance(em, card, opts = {}) {
|
|||||||
await fetch(`${API_BASE}/api/email/delete/${em.uid}?folder=${encodeURIComponent(state._libFolder)}${_acct()}`, { method: 'DELETE' });
|
await fetch(`${API_BASE}/api/email/delete/${em.uid}?folder=${encodeURIComponent(state._libFolder)}${_acct()}`, { method: 'DELETE' });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to delete email:', err);
|
console.error('Failed to delete email:', err);
|
||||||
|
busy?.remove?.();
|
||||||
showToast('Failed to delete email');
|
showToast('Failed to delete email');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
busy?.remove?.();
|
||||||
await _animateEmailCardRemoval([em.uid]);
|
await _animateEmailCardRemoval([em.uid]);
|
||||||
state._libEmails = state._libEmails.filter(e => String(e.uid) !== String(em.uid));
|
state._libEmails = state._libEmails.filter(e => String(e.uid) !== String(em.uid));
|
||||||
state._selectedUids.delete(em.uid);
|
state._selectedUids.delete(em.uid);
|
||||||
@@ -752,6 +755,29 @@ async function _deleteEmailAndAdvance(em, card, opts = {}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _showEmailDeleteOverlay(target) {
|
||||||
|
if (!target) return null;
|
||||||
|
const wp = spinnerModule.createWhirlpool(18);
|
||||||
|
const overlay = document.createElement('div');
|
||||||
|
overlay.className = 'email-delete-overlay';
|
||||||
|
overlay.appendChild(wp.element);
|
||||||
|
const prevPos = target.style.position;
|
||||||
|
const prevPointerEvents = target.style.pointerEvents;
|
||||||
|
if (getComputedStyle(target).position === 'static') target.style.position = 'relative';
|
||||||
|
target.style.pointerEvents = 'none';
|
||||||
|
target.classList.add('email-delete-busy');
|
||||||
|
target.appendChild(overlay);
|
||||||
|
return {
|
||||||
|
remove() {
|
||||||
|
try { wp.destroy?.(); } catch (_) {}
|
||||||
|
overlay.remove();
|
||||||
|
target.classList.remove('email-delete-busy');
|
||||||
|
target.style.pointerEvents = prevPointerEvents;
|
||||||
|
target.style.position = prevPos;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function _animateEmailCardRemoval(uids, opts = {}) {
|
function _animateEmailCardRemoval(uids, opts = {}) {
|
||||||
const uidSet = new Set((uids || []).map(uid => String(uid)));
|
const uidSet = new Set((uids || []).map(uid => String(uid)));
|
||||||
if (!uidSet.size) return Promise.resolve();
|
if (!uidSet.size) return Promise.resolve();
|
||||||
@@ -6555,9 +6581,16 @@ function _showReaderMoreMenu(em, card, reader, anchor) {
|
|||||||
label: 'Move to Trash',
|
label: 'Move to Trash',
|
||||||
icon: _trashIcon,
|
icon: _trashIcon,
|
||||||
action: async () => {
|
action: async () => {
|
||||||
|
const busy = _showEmailDeleteOverlay(card);
|
||||||
try {
|
try {
|
||||||
await fetch(`${API_BASE}/api/email/delete/${em.uid}?folder=${encodeURIComponent(state._libFolder)}${_acct()}`, { method: 'DELETE' });
|
await fetch(`${API_BASE}/api/email/delete/${em.uid}?folder=${encodeURIComponent(state._libFolder)}${_acct()}`, { method: 'DELETE' });
|
||||||
} catch (e) { console.error(e); }
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
busy?.remove?.();
|
||||||
|
showToast('Failed to delete email');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
busy?.remove?.();
|
||||||
await closeAndRemove();
|
await closeAndRemove();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -6572,9 +6605,16 @@ function _showReaderMoreMenu(em, card, reader, anchor) {
|
|||||||
{ confirmText: 'Delete', cancelText: 'Cancel', danger: true }
|
{ confirmText: 'Delete', cancelText: 'Cancel', danger: true }
|
||||||
);
|
);
|
||||||
if (!ok) return;
|
if (!ok) return;
|
||||||
|
const busy = _showEmailDeleteOverlay(card);
|
||||||
try {
|
try {
|
||||||
await fetch(`${API_BASE}/api/email/delete-permanent/${em.uid}?folder=${encodeURIComponent(state._libFolder)}${_acct()}`, { method: 'DELETE' });
|
await fetch(`${API_BASE}/api/email/delete-permanent/${em.uid}?folder=${encodeURIComponent(state._libFolder)}${_acct()}`, { method: 'DELETE' });
|
||||||
} catch (e) { console.error(e); }
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
busy?.remove?.();
|
||||||
|
showToast('Failed to delete email');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
busy?.remove?.();
|
||||||
await closeAndRemove();
|
await closeAndRemove();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -29296,6 +29296,27 @@ button .spinner-whirlpool {
|
|||||||
0 0 12px -3px color-mix(in srgb, var(--accent, var(--red)) 65%, transparent);
|
0 0 12px -3px color-mix(in srgb, var(--accent, var(--red)) 65%, transparent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.email-delete-busy {
|
||||||
|
opacity: 0.72;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-delete-overlay {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 8;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: inherit;
|
||||||
|
background: color-mix(in srgb, var(--panel, var(--bg)) 82%, transparent);
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-delete-overlay .spinner-whirlpool,
|
||||||
|
.email-delete-overlay .ai-spinner-whirlpool {
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
.doclib-card.email-card-removing {
|
.doclib-card.email-card-removing {
|
||||||
pointer-events: none !important;
|
pointer-events: none !important;
|
||||||
max-height: 0 !important;
|
max-height: 0 !important;
|
||||||
|
|||||||
Reference in New Issue
Block a user