mirror of
https://github.com/mjl-/mox.git
synced 2024-12-26 00:13:47 +03:00
webmail: fix using the compose window/popup after saving a draft message failed
we kept the "save draft" promise, and would wait for it again for other operations (eg close, save again, send), which wouldn't make progress. can easily be reproduced by saving a message with a control character in an address or the subject. saving the draft will fail. for issue #256 by ally9335, thanks for reporting
This commit is contained in:
parent
bd693805fd
commit
ee48cf0dfd
2 changed files with 21 additions and 12 deletions
|
@ -2581,7 +2581,7 @@ const compose = (opts, listMailboxes) => {
|
|||
let draftSaveTimer = 0;
|
||||
let draftSavePromise = Promise.resolve(0);
|
||||
let draftLastText = opts.body;
|
||||
const draftCancelSave = () => {
|
||||
const draftCancelSaveTimer = () => {
|
||||
if (draftSaveTimer) {
|
||||
window.clearTimeout(draftSaveTimer);
|
||||
draftSaveTimer = 0;
|
||||
|
@ -2598,7 +2598,7 @@ const compose = (opts, listMailboxes) => {
|
|||
}, 60 * 1000);
|
||||
};
|
||||
const draftSave = async () => {
|
||||
draftCancelSave();
|
||||
draftCancelSaveTimer();
|
||||
let replyTo = '';
|
||||
if (replytoViews && replytoViews.length === 1 && replytoViews[0].input.value) {
|
||||
replyTo = replytoViews[0].input.value;
|
||||
|
@ -2619,7 +2619,12 @@ const compose = (opts, listMailboxes) => {
|
|||
throw new Error('no designated drafts mailbox');
|
||||
}
|
||||
draftSavePromise = client.MessageCompose(cm, mbdrafts.ID);
|
||||
try {
|
||||
draftMessageID = await draftSavePromise;
|
||||
}
|
||||
finally {
|
||||
draftSavePromise = Promise.resolve(0);
|
||||
}
|
||||
draftLastText = cm.TextBody;
|
||||
};
|
||||
// todo future: on visibilitychange with visibilityState "hidden", use navigator.sendBeacon to save latest modified draft message?
|
||||
|
@ -2630,7 +2635,7 @@ const compose = (opts, listMailboxes) => {
|
|||
// triggered. But we still have the beforeunload handler that checks for
|
||||
// unsavedChanges to protect the user in such cases.
|
||||
const cmdClose = async () => {
|
||||
draftCancelSave();
|
||||
draftCancelSaveTimer();
|
||||
await draftSavePromise;
|
||||
if (unsavedChanges()) {
|
||||
const action = await new Promise((resolve) => {
|
||||
|
@ -2664,12 +2669,12 @@ const compose = (opts, listMailboxes) => {
|
|||
composeView = null;
|
||||
};
|
||||
const cmdSave = async () => {
|
||||
draftCancelSave();
|
||||
draftCancelSaveTimer();
|
||||
await draftSavePromise;
|
||||
await withStatus('Saving draft', draftSave());
|
||||
};
|
||||
const submit = async (archive) => {
|
||||
draftCancelSave();
|
||||
draftCancelSaveTimer();
|
||||
await draftSavePromise;
|
||||
const files = await new Promise((resolve, reject) => {
|
||||
const l = [];
|
||||
|
|
|
@ -1464,7 +1464,7 @@ const compose = (opts: ComposeOptions, listMailboxes: listMailboxes) => {
|
|||
let draftSavePromise = Promise.resolve(0)
|
||||
let draftLastText = opts.body
|
||||
|
||||
const draftCancelSave = () => {
|
||||
const draftCancelSaveTimer = () => {
|
||||
if (draftSaveTimer) {
|
||||
window.clearTimeout(draftSaveTimer)
|
||||
draftSaveTimer = 0
|
||||
|
@ -1483,7 +1483,7 @@ const compose = (opts: ComposeOptions, listMailboxes: listMailboxes) => {
|
|||
}
|
||||
|
||||
const draftSave = async () => {
|
||||
draftCancelSave()
|
||||
draftCancelSaveTimer()
|
||||
let replyTo = ''
|
||||
if (replytoViews && replytoViews.length === 1 && replytoViews[0].input.value) {
|
||||
replyTo = replytoViews[0].input.value
|
||||
|
@ -1504,7 +1504,11 @@ const compose = (opts: ComposeOptions, listMailboxes: listMailboxes) => {
|
|||
throw new Error('no designated drafts mailbox')
|
||||
}
|
||||
draftSavePromise = client.MessageCompose(cm, mbdrafts.ID)
|
||||
try {
|
||||
draftMessageID = await draftSavePromise
|
||||
} finally {
|
||||
draftSavePromise = Promise.resolve(0)
|
||||
}
|
||||
draftLastText = cm.TextBody
|
||||
}
|
||||
|
||||
|
@ -1518,7 +1522,7 @@ const compose = (opts: ComposeOptions, listMailboxes: listMailboxes) => {
|
|||
// triggered. But we still have the beforeunload handler that checks for
|
||||
// unsavedChanges to protect the user in such cases.
|
||||
const cmdClose = async () => {
|
||||
draftCancelSave()
|
||||
draftCancelSaveTimer()
|
||||
await draftSavePromise
|
||||
if (unsavedChanges()) {
|
||||
const action = await new Promise<string>((resolve) => {
|
||||
|
@ -1560,13 +1564,13 @@ const compose = (opts: ComposeOptions, listMailboxes: listMailboxes) => {
|
|||
}
|
||||
|
||||
const cmdSave = async () => {
|
||||
draftCancelSave()
|
||||
draftCancelSaveTimer()
|
||||
await draftSavePromise
|
||||
await withStatus('Saving draft', draftSave())
|
||||
}
|
||||
|
||||
const submit = async (archive: boolean) => {
|
||||
draftCancelSave()
|
||||
draftCancelSaveTimer()
|
||||
await draftSavePromise
|
||||
|
||||
const files = await new Promise<api.File[]>((resolve, reject) => {
|
||||
|
|
Loading…
Reference in a new issue