Add notices on action completion

This commit is contained in:
Drew DeVault 2020-11-19 11:17:40 -05:00
parent 405c18d213
commit cb37df882e
6 changed files with 33 additions and 1 deletions

View File

@ -306,6 +306,7 @@ func handleDeleteMailbox(ctx *alps.Context) error {
ctx.Session.DoIMAP(func(c *imapclient.Client) error { ctx.Session.DoIMAP(func(c *imapclient.Client) error {
return c.Delete(mbox.Name) return c.Delete(mbox.Name)
}) })
ctx.Session.PutNotice("Mailbox deleted.")
return ctx.Redirect(http.StatusFound, "/mailbox/INBOX") return ctx.Redirect(http.StatusFound, "/mailbox/INBOX")
} }
@ -519,6 +520,7 @@ func submitCompose(ctx *alps.Context, msg *OutgoingMessage, options *composeOpti
return fmt.Errorf("failed to save message to Sent mailbox: %v", err) return fmt.Errorf("failed to save message to Sent mailbox: %v", err)
} }
ctx.Session.PutNotice("Message sent.")
return ctx.Redirect(http.StatusFound, "/mailbox/INBOX") return ctx.Redirect(http.StatusFound, "/mailbox/INBOX")
} }
@ -651,6 +653,7 @@ 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)
} }
ctx.Session.PutNotice("Message saved as draft.")
return ctx.Redirect(http.StatusFound, fmt.Sprintf( return ctx.Redirect(http.StatusFound, fmt.Sprintf(
"/message/%s/%d/edit?part=1", drafts.Name, uid)) "/message/%s/%d/edit?part=1", drafts.Name, uid))
} else { } else {
@ -981,6 +984,7 @@ func handleMove(ctx *alps.Context) error {
return err return err
} }
ctx.Session.PutNotice("Message(s) moved.")
if path := formOrQueryParam(ctx, "next"); path != "" { if path := formOrQueryParam(ctx, "next"); path != "" {
return ctx.Redirect(http.StatusFound, path) return ctx.Redirect(http.StatusFound, path)
} }
@ -1032,6 +1036,7 @@ func handleDelete(ctx *alps.Context) error {
return err return err
} }
ctx.Session.PutNotice("Message(s) deleted.")
if path := formOrQueryParam(ctx, "next"); path != "" { if path := formOrQueryParam(ctx, "next"); path != "" {
return ctx.Redirect(http.StatusFound, path) return ctx.Redirect(http.StatusFound, path)
} }

View File

@ -28,6 +28,8 @@ type GlobalRenderData struct {
HavePlugin func(name string) bool HavePlugin func(name string) bool
Notice string
// additional plugin-specific data // additional plugin-specific data
Extra map[string]interface{} Extra map[string]interface{}
} }
@ -95,6 +97,7 @@ func NewBaseRenderData(ectx echo.Context) *BaseRenderData {
if isactx && ctx.Session != nil { if isactx && ctx.Session != nil {
global.LoggedIn = true global.LoggedIn = true
global.Username = ctx.Session.username global.Username = ctx.Session.username
global.Notice = ctx.Session.PopNotice()
} }
return &BaseRenderData{ return &BaseRenderData{

View File

@ -57,6 +57,7 @@ type Session struct {
pings chan struct{} pings chan struct{}
timer *time.Timer timer *time.Timer
store Store store Store
notice string
imapLocker sync.Mutex imapLocker sync.Mutex
imapConn *imapclient.Client // protected by locker, can be nil imapConn *imapclient.Client // protected by locker, can be nil
@ -183,6 +184,16 @@ func (s *Session) PopAttachment(uuid string) *Attachment {
return a return a
} }
func (s *Session) PutNotice(n string) {
s.notice = n
}
func (s *Session) PopNotice() string {
n := s.notice
s.notice = ""
return n
}
// Store returns a store suitable for storing persistent user data. // Store returns a store suitable for storing persistent user data.
func (s *Session) Store() Store { func (s *Session) Store() Store {
return s.store return s.store

View File

@ -118,6 +118,13 @@ header nav div { float: right; }
header nav div > a{ margin-left: 1rem; } header nav div > a{ margin-left: 1rem; }
header a.active { font-weight: bold; color: black; text-decoration: none; } header a.active { font-weight: bold; color: black; text-decoration: none; }
header .notice {
color: #0c5460;
background-color: #d1ecf1;
border: 1px solid #bee5eb;
padding: 0.5rem;
text-align: center;
}
footer { text-align: right; } footer { text-align: right; }

View File

@ -21,7 +21,7 @@
{{ $classes = printf "%s %s" $classes "message-list-deleted" }} {{ $classes = printf "%s %s" $classes "message-list-deleted" }}
{{ end }} {{ end }}
{{ if not (.HasFlag "\\Deleted") }} {{ if and (not (.HasFlag "\\Deleted")) .Envelope }}
<div class="message-list-checkbox {{$classes}}"> <div class="message-list-checkbox {{$classes}}">
<input type="checkbox" name="uids" value="{{.Uid}}" form="messages-form"> <input type="checkbox" name="uids" value="{{.Uid}}" form="messages-form">
</div> </div>

View File

@ -30,4 +30,10 @@
</div> </div>
{{ end }} {{ end }}
</nav> </nav>
{{ if .GlobalData.Notice }}
<div class="notice">
{{ .GlobalData.Notice }}
<a href="{{.GlobalData.URL.String}}">Dismiss</a>
</div>
{{ end }}
</header> </header>