Redirect to edit draft after saving message
This commit is contained in:
parent
12547e2654
commit
1321cea241
|
@ -9,6 +9,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
nettextproto "net/textproto"
|
||||||
|
|
||||||
"github.com/dustin/go-humanize"
|
"github.com/dustin/go-humanize"
|
||||||
"github.com/emersion/go-imap"
|
"github.com/emersion/go-imap"
|
||||||
|
@ -570,20 +571,20 @@ func markMessageAnswered(conn *imapclient.Client, mboxName string, uid uint32) e
|
||||||
return conn.UidStore(seqSet, item, flags, nil)
|
return conn.UidStore(seqSet, item, flags, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func appendMessage(c *imapclient.Client, msg *OutgoingMessage, mboxType mailboxType) (saved bool, err error) {
|
func appendMessage(c *imapclient.Client, msg *OutgoingMessage, mboxType mailboxType) (*MailboxInfo, uint32, error) {
|
||||||
mbox, err := getMailboxByType(c, mboxType)
|
mbox, err := getMailboxByType(c, mboxType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
if mbox == nil {
|
if mbox == nil {
|
||||||
return false, nil
|
return nil, 0, fmt.Errorf("Unable to resolve mailbox")
|
||||||
}
|
}
|
||||||
|
|
||||||
// IMAP needs to know in advance the final size of the message, so
|
// IMAP needs to know in advance the final size of the message, so
|
||||||
// there's no way around storing it in a buffer here.
|
// there's no way around storing it in a buffer here.
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
if err := msg.WriteTo(&buf); err != nil {
|
if err := msg.WriteTo(&buf); err != nil {
|
||||||
return false, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
flags := []string{imap.SeenFlag}
|
flags := []string{imap.SeenFlag}
|
||||||
|
@ -591,10 +592,20 @@ func appendMessage(c *imapclient.Client, msg *OutgoingMessage, mboxType mailboxT
|
||||||
flags = append(flags, imap.DraftFlag)
|
flags = append(flags, imap.DraftFlag)
|
||||||
}
|
}
|
||||||
if err := c.Append(mbox.Name, flags, time.Now(), &buf); err != nil {
|
if err := c.Append(mbox.Name, flags, time.Now(), &buf); err != nil {
|
||||||
return false, err
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
criteria := &imap.SearchCriteria{
|
||||||
|
Header: make(nettextproto.MIMEHeader),
|
||||||
|
}
|
||||||
|
criteria.Header.Add("Message-Id", msg.MessageID)
|
||||||
|
if uids, err := c.UidSearch(criteria); err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
} else {
|
||||||
|
if len(uids) != 1 {
|
||||||
|
panic(fmt.Errorf("Duplicate message ID"))
|
||||||
|
}
|
||||||
|
return mbox, uids[0], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return true, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteMessage(c *imapclient.Client, mboxName string, uid uint32) error {
|
func deleteMessage(c *imapclient.Client, mboxName string, uid uint32) error {
|
||||||
|
|
|
@ -507,7 +507,7 @@ func submitCompose(ctx *alps.Context, msg *OutgoingMessage, options *composeOpti
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ctx.Session.DoIMAP(func(c *imapclient.Client) error {
|
err = ctx.Session.DoIMAP(func(c *imapclient.Client) error {
|
||||||
if _, err := appendMessage(c, msg, mailboxSent); err != nil {
|
if _, _, err := appendMessage(c, msg, mailboxSent); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if draft := options.Draft; draft != nil {
|
if draft := options.Draft; draft != nil {
|
||||||
|
@ -620,14 +620,15 @@ func handleCompose(ctx *alps.Context, msg *OutgoingMessage, options *composeOpti
|
||||||
}
|
}
|
||||||
|
|
||||||
if saveAsDraft {
|
if saveAsDraft {
|
||||||
|
var (
|
||||||
|
drafts *MailboxInfo
|
||||||
|
uid uint32
|
||||||
|
)
|
||||||
err = ctx.Session.DoIMAP(func(c *imapclient.Client) error {
|
err = ctx.Session.DoIMAP(func(c *imapclient.Client) error {
|
||||||
copied, err := appendMessage(c, msg, mailboxDrafts)
|
drafts, uid, err = appendMessage(c, msg, mailboxDrafts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !copied {
|
|
||||||
return fmt.Errorf("no Draft mailbox found")
|
|
||||||
}
|
|
||||||
if draft := options.Draft; draft != nil {
|
if draft := options.Draft; draft != nil {
|
||||||
if err := deleteMessage(c, draft.Mailbox, draft.Uid); err != nil {
|
if err := deleteMessage(c, draft.Mailbox, draft.Uid); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -638,7 +639,8 @@ func handleCompose(ctx *alps.Context, msg *OutgoingMessage, options *composeOpti
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to save message to Draft mailbox: %v", err)
|
return fmt.Errorf("failed to save message to Draft mailbox: %v", err)
|
||||||
}
|
}
|
||||||
return ctx.Redirect(http.StatusFound, "/mailbox/INBOX")
|
return ctx.Redirect(http.StatusFound, fmt.Sprintf(
|
||||||
|
"/message/%s/%d/edit?part=1", drafts.Name, uid))
|
||||||
} else {
|
} else {
|
||||||
return submitCompose(ctx, msg, options)
|
return submitCompose(ctx, msg, options)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
const sendButton = document.getElementById("send-button"),
|
||||||
|
saveButton = document.getElementById("save-button");
|
||||||
|
|
||||||
const composeForm = document.getElementById("compose-form");
|
const composeForm = document.getElementById("compose-form");
|
||||||
const sendProgress = document.getElementById("send-progress");
|
const sendProgress = document.getElementById("send-progress");
|
||||||
composeForm.addEventListener("submit", ev => {
|
composeForm.addEventListener("submit", ev => {
|
||||||
|
@ -6,6 +9,10 @@ composeForm.addEventListener("submit", ev => {
|
||||||
sendProgress.style.display = 'flex';
|
sendProgress.style.display = 'flex';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
saveButton.addEventListener("click", ev => {
|
||||||
|
sendProgress.querySelector(".info").innerText = "Saving draft...";
|
||||||
|
});
|
||||||
|
|
||||||
let attachments = [];
|
let attachments = [];
|
||||||
|
|
||||||
const headers = document.querySelector(".create-update .headers");
|
const headers = document.querySelector(".create-update .headers");
|
||||||
|
@ -41,9 +48,6 @@ function dragNOP(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
const sendButton = document.getElementById("send-button"),
|
|
||||||
saveButton = document.getElementById("save-button");
|
|
||||||
|
|
||||||
const attachmentUUIDsNode = document.getElementById("attachment-uuids");
|
const attachmentUUIDsNode = document.getElementById("attachment-uuids");
|
||||||
function updateState() {
|
function updateState() {
|
||||||
let complete = true;
|
let complete = true;
|
||||||
|
|
|
@ -70,7 +70,7 @@
|
||||||
License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
||||||
-->
|
-->
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M288 39.056v16.659c0 10.804 7.281 20.159 17.686 23.066C383.204 100.434 440 171.518 440 256c0 101.689-82.295 184-184 184-101.689 0-184-82.295-184-184 0-84.47 56.786-155.564 134.312-177.219C216.719 75.874 224 66.517 224 55.712V39.064c0-15.709-14.834-27.153-30.046-23.234C86.603 43.482 7.394 141.206 8.003 257.332c.72 137.052 111.477 246.956 248.531 246.667C393.255 503.711 504 392.788 504 256c0-115.633-79.14-212.779-186.211-240.236C302.678 11.889 288 23.456 288 39.056z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M288 39.056v16.659c0 10.804 7.281 20.159 17.686 23.066C383.204 100.434 440 171.518 440 256c0 101.689-82.295 184-184 184-101.689 0-184-82.295-184-184 0-84.47 56.786-155.564 134.312-177.219C216.719 75.874 224 66.517 224 55.712V39.064c0-15.709-14.834-27.153-30.046-23.234C86.603 43.482 7.394 141.206 8.003 257.332c.72 137.052 111.477 246.956 248.531 246.667C393.255 503.711 504 392.788 504 256c0-115.633-79.14-212.779-186.211-240.236C302.678 11.889 288 23.456 288 39.056z"/></svg>
|
||||||
<span>Sending message...</span>
|
<span class="info">Sending message...</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue