plugins/base: allow move/delete/flag operations to take multiple UIDs
This commit is contained in:
parent
fe73f2022c
commit
b61e40f363
14
go.mod
14
go.mod
|
@ -5,8 +5,9 @@ go 1.13
|
|||
require (
|
||||
github.com/aymerick/douceur v0.2.0
|
||||
github.com/chris-ramon/douceur v0.2.0
|
||||
github.com/emersion/go-ical v0.0.0-20200225182515-5cc64a0054ad // indirect
|
||||
github.com/emersion/go-imap v1.0.3
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
|
||||
github.com/emersion/go-ical v0.0.0-20200225233454-26ef720b8bf1 // indirect
|
||||
github.com/emersion/go-imap v1.0.4
|
||||
github.com/emersion/go-imap-metadata v0.0.0-20200128185110-9d939d2a0915
|
||||
github.com/emersion/go-imap-move v0.0.0-20190710073258-6e5a51a5b342
|
||||
github.com/emersion/go-imap-specialuse v0.0.0-20161227184202-ba031ced6a62
|
||||
|
@ -17,14 +18,13 @@ require (
|
|||
github.com/emersion/go-webdav v0.2.1-0.20200227113614-abadf534f49a
|
||||
github.com/google/uuid v1.1.1
|
||||
github.com/gorilla/css v1.0.0 // indirect
|
||||
github.com/labstack/echo/v4 v4.1.15-0.20200203180927-504f39abaf32
|
||||
github.com/labstack/echo/v4 v4.1.15
|
||||
github.com/labstack/gommon v0.3.0
|
||||
github.com/mattn/go-isatty v0.0.12 // indirect
|
||||
github.com/microcosm-cc/bluemonday v1.0.2
|
||||
github.com/yuin/gopher-lua v0.0.0-20191220021717-ab39c6098bdb
|
||||
gitlab.com/golang-commonmark/linkify v0.0.0-20200225224916-64bca66f6ad3
|
||||
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d // indirect
|
||||
golang.org/x/net v0.0.0-20200225223329-5d076fcf07a8
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae // indirect
|
||||
golang.org/x/crypto v0.0.0-20200317142112-1b76d66859c6 // indirect
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a
|
||||
golang.org/x/sys v0.0.0-20200317113312-5766fd39f98d // indirect
|
||||
layeh.com/gopher-luar v1.0.7
|
||||
)
|
||||
|
|
28
go.sum
28
go.sum
|
@ -12,10 +12,12 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumC
|
|||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/emersion/go-ical v0.0.0-20200224201310-cd514449c39e h1:YGM1sI7edZOt8KAfX9Miq/X99d2QXdgjkJ7vN4HjxAA=
|
||||
github.com/emersion/go-ical v0.0.0-20200224201310-cd514449c39e/go.mod h1:4xVTBPcT43a1pp3vdaa+FuRdX5XhKCZPpWv7m0z9ByM=
|
||||
github.com/emersion/go-ical v0.0.0-20200225182515-5cc64a0054ad h1:OKhKFSWeuAbVzgBsas+QCjCFLzi7pRX/FEhDudYHiQw=
|
||||
github.com/emersion/go-ical v0.0.0-20200225182515-5cc64a0054ad/go.mod h1:4xVTBPcT43a1pp3vdaa+FuRdX5XhKCZPpWv7m0z9ByM=
|
||||
github.com/emersion/go-ical v0.0.0-20200225233454-26ef720b8bf1 h1:v0W797seT60q3pzrphQUKh22Nt8uS7rgZyD6lqYgM0E=
|
||||
github.com/emersion/go-ical v0.0.0-20200225233454-26ef720b8bf1/go.mod h1:4xVTBPcT43a1pp3vdaa+FuRdX5XhKCZPpWv7m0z9ByM=
|
||||
github.com/emersion/go-imap v1.0.3 h1:5eEee8/DTSIPfliiWqwfvjPGkU8bBtvOy/Wx+eeXzO4=
|
||||
github.com/emersion/go-imap v1.0.3/go.mod h1:yKASt+C3ZiDAiCSssxg9caIckWF/JG7ZQTO7GAmvicU=
|
||||
github.com/emersion/go-imap v1.0.4 h1:uiCAIHM6Z5Jwkma1zdNDWWXxSCqb+/xHBkHflD7XBro=
|
||||
github.com/emersion/go-imap v1.0.4/go.mod h1:yKASt+C3ZiDAiCSssxg9caIckWF/JG7ZQTO7GAmvicU=
|
||||
github.com/emersion/go-imap-metadata v0.0.0-20200128185110-9d939d2a0915 h1:8xzODjLqrfAJo+CNhX0Fp47vdVN0ZvmGV3CPt/Ex1nU=
|
||||
github.com/emersion/go-imap-metadata v0.0.0-20200128185110-9d939d2a0915/go.mod h1:6mXMzbK9Ts0mrrBibqy56SqZpuFMry5AedTgu6qY5zM=
|
||||
github.com/emersion/go-imap-move v0.0.0-20190710073258-6e5a51a5b342 h1:5p1t3e1PomYgLWwEwhwEU5kVBwcyAcVrOpexv8AeZx0=
|
||||
|
@ -39,18 +41,17 @@ github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
|||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
|
||||
github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
|
||||
github.com/labstack/echo/v4 v4.1.15-0.20200203180927-504f39abaf32 h1:UiIEDYxPPmjl6mMIY4QPDguD/QAtK+gR4IRMSrjWmeA=
|
||||
github.com/labstack/echo/v4 v4.1.15-0.20200203180927-504f39abaf32/go.mod h1:mbsytw7LXzfWxMLdvzjjeERCwTL3PI03GIPpUpaMnfQ=
|
||||
github.com/labstack/echo/v4 v4.1.15 h1:4aE6KfJC+wCnMjODwcpeEGWGsRfszxZMwB3QVTECj2I=
|
||||
github.com/labstack/echo/v4 v4.1.15/go.mod h1:GWO5IBVzI371K8XJe50CSvHjQCafK6cw8R/moLhEU6o=
|
||||
github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0=
|
||||
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
|
||||
github.com/martinlindhe/base36 v1.0.0 h1:eYsumTah144C0A8P1T/AVSUk5ZoLnhfYFM3OGQxB52A=
|
||||
github.com/martinlindhe/base36 v1.0.0/go.mod h1:+AtEs8xrBpCeYgSLoY/aJ6Wf37jtBuR0s35750M27+8=
|
||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
|
||||
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
||||
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/microcosm-cc/bluemonday v1.0.2 h1:5lPfLTTAvAbtS0VqT+94yOtFnGfUWYyx0+iToC3Os3s=
|
||||
|
@ -72,24 +73,25 @@ github.com/yuin/gopher-lua v0.0.0-20191220021717-ab39c6098bdb/go.mod h1:gqRgreBU
|
|||
gitlab.com/golang-commonmark/linkify v0.0.0-20200225224916-64bca66f6ad3 h1:1Coh5BsUBlXoEJmIEaNzVAWrtg9k7/eJzailMQr1grw=
|
||||
gitlab.com/golang-commonmark/linkify v0.0.0-20200225224916-64bca66f6ad3/go.mod h1:Gn+LZmCrhPECMD3SOKlE+BOHwhOYD9j7WT9NUtkCrC8=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d h1:1ZiEyfaQIg3Qh0EoqpwAakHVhecoE5wlSg5GjnafJGw=
|
||||
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200317142112-1b76d66859c6 h1:TjszyFsQsyZNHwdVdZ5m7bjmreu0znc2kRYsEml9/Ww=
|
||||
golang.org/x/crypto v0.0.0-20200317142112-1b76d66859c6/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200225223329-5d076fcf07a8 h1:0hpG1RSqNmKZ60akfzABaMjKAn2762l2+HJyXFT5LMY=
|
||||
golang.org/x/net v0.0.0-20200225223329-5d076fcf07a8/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200317113312-5766fd39f98d h1:62ap6LNOjDU6uGmKXHJbSfciMoV+FeI1sRXx/pLDL44=
|
||||
golang.org/x/sys v0.0.0-20200317113312-5766fd39f98d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
{{end}}
|
||||
</h2>
|
||||
|
||||
<form method="post" action="{{.Message.URL}}/move">
|
||||
<form method="post" action="/message/{{.Mailbox.Name | pathescape}}/move">
|
||||
<input type="hidden" name="uids" value="{{.Message.Uid}}">
|
||||
<label for="move-to">Move to:</label>
|
||||
<select name="to" id="move-to">
|
||||
{{range .Mailboxes}}
|
||||
|
@ -26,12 +27,14 @@
|
|||
<input type="submit" value="Move">
|
||||
</form>
|
||||
|
||||
<form method="post" action="{{.Message.URL}}/delete">
|
||||
<form method="post" action="/message/{{.Mailbox.Name | pathescape}}/delete">
|
||||
<input type="hidden" name="uids" value="{{.Message.Uid}}">
|
||||
<input type="submit" value="Delete">
|
||||
</form>
|
||||
|
||||
{{if .Flags}}
|
||||
<form method="post" action="{{.Message.URL}}/flag">
|
||||
<form method="post" action="/message/{{.Mailbox.Name | pathescape}}/flag">
|
||||
<input type="hidden" name="uids" value="{{.Message.Uid}}">
|
||||
<p>Flags:</p>
|
||||
{{range $name, $has := .Flags}}
|
||||
{{if ismutableflag $name}}
|
||||
|
|
|
@ -53,11 +53,11 @@ func registerRoutes(p *koushin.GoPlugin) {
|
|||
p.GET("/message/:mbox/:uid/edit", handleEdit)
|
||||
p.POST("/message/:mbox/:uid/edit", handleEdit)
|
||||
|
||||
p.POST("/message/:mbox/:uid/move", handleMove)
|
||||
p.POST("/message/:mbox/move", handleMove)
|
||||
|
||||
p.POST("/message/:mbox/:uid/delete", handleDelete)
|
||||
p.POST("/message/:mbox/delete", handleDelete)
|
||||
|
||||
p.POST("/message/:mbox/:uid/flag", handleSetFlags)
|
||||
p.POST("/message/:mbox/flag", handleSetFlags)
|
||||
|
||||
p.GET("/settings", handleSettings)
|
||||
p.POST("/settings", handleSettings)
|
||||
|
@ -654,7 +654,16 @@ func handleEdit(ctx *koushin.Context) error {
|
|||
}
|
||||
|
||||
func handleMove(ctx *koushin.Context) error {
|
||||
mboxName, uid, err := parseMboxAndUid(ctx.Param("mbox"), ctx.Param("uid"))
|
||||
mboxName, err := url.PathUnescape(ctx.Param("mbox"))
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, err)
|
||||
}
|
||||
|
||||
formParams, err := ctx.FormParams()
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, err)
|
||||
}
|
||||
uids, err := parseUidList(formParams["uids"])
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, err)
|
||||
}
|
||||
|
@ -669,7 +678,7 @@ func handleMove(ctx *koushin.Context) error {
|
|||
}
|
||||
|
||||
var seqSet imap.SeqSet
|
||||
seqSet.AddNum(uid)
|
||||
seqSet.AddNum(uids...)
|
||||
if err := mc.UidMoveWithFallback(&seqSet, to); err != nil {
|
||||
return fmt.Errorf("failed to move message: %v", err)
|
||||
}
|
||||
|
@ -685,7 +694,16 @@ func handleMove(ctx *koushin.Context) error {
|
|||
}
|
||||
|
||||
func handleDelete(ctx *koushin.Context) error {
|
||||
mboxName, uid, err := parseMboxAndUid(ctx.Param("mbox"), ctx.Param("uid"))
|
||||
mboxName, err := url.PathUnescape(ctx.Param("mbox"))
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, err)
|
||||
}
|
||||
|
||||
formParams, err := ctx.FormParams()
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, err)
|
||||
}
|
||||
uids, err := parseUidList(formParams["uids"])
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, err)
|
||||
}
|
||||
|
@ -696,7 +714,7 @@ func handleDelete(ctx *koushin.Context) error {
|
|||
}
|
||||
|
||||
var seqSet imap.SeqSet
|
||||
seqSet.AddNum(uid)
|
||||
seqSet.AddNum(uids...)
|
||||
|
||||
item := imap.FormatFlagsOp(imap.AddFlags, true)
|
||||
flags := []interface{}{imap.DeletedFlag}
|
||||
|
@ -724,16 +742,20 @@ func handleDelete(ctx *koushin.Context) error {
|
|||
}
|
||||
|
||||
func handleSetFlags(ctx *koushin.Context) error {
|
||||
mboxName, uid, err := parseMboxAndUid(ctx.Param("mbox"), ctx.Param("uid"))
|
||||
mboxName, err := url.PathUnescape(ctx.Param("mbox"))
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, err)
|
||||
}
|
||||
|
||||
form, err := ctx.FormParams()
|
||||
formParams, err := ctx.FormParams()
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, err)
|
||||
}
|
||||
flags, ok := form["flags"]
|
||||
uids, err := parseUidList(formParams["uids"])
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, err)
|
||||
}
|
||||
flags, ok := formParams["flags"]
|
||||
if !ok {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "missing 'flags' form values")
|
||||
}
|
||||
|
@ -756,7 +778,7 @@ func handleSetFlags(ctx *koushin.Context) error {
|
|||
}
|
||||
|
||||
var seqSet imap.SeqSet
|
||||
seqSet.AddNum(uid)
|
||||
seqSet.AddNum(uids...)
|
||||
|
||||
storeItems := make([]interface{}, len(flags))
|
||||
for i, f := range flags {
|
||||
|
@ -774,11 +796,11 @@ func handleSetFlags(ctx *koushin.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if op == imap.RemoveFlags && len(flags) == 1 && flags[0] == "\\Seen" {
|
||||
if len(uids) != 1 || (op == imap.RemoveFlags && len(flags) == 1 && flags[0] == "\\Seen") {
|
||||
// Redirecting to the message view would mark the message as read again
|
||||
return ctx.Redirect(http.StatusFound, fmt.Sprintf("/mailbox/%v", url.PathEscape(mboxName)))
|
||||
}
|
||||
return ctx.Redirect(http.StatusFound, fmt.Sprintf("/message/%v/%v", url.PathEscape(mboxName), uid))
|
||||
return ctx.Redirect(http.StatusFound, fmt.Sprintf("/message/%v/%v", url.PathEscape(mboxName), uids[0]))
|
||||
}
|
||||
|
||||
const settingsKey = "base.settings"
|
||||
|
|
|
@ -27,6 +27,18 @@ func parseMboxAndUid(mboxString, uidString string) (string, uint32, error) {
|
|||
return mboxName, uid, err
|
||||
}
|
||||
|
||||
func parseUidList(values []string) ([]uint32, error) {
|
||||
var uids []uint32
|
||||
for _, v := range values {
|
||||
uid, err := parseUid(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uids = append(uids, uid)
|
||||
}
|
||||
return uids, nil
|
||||
}
|
||||
|
||||
func parsePartPath(s string) ([]int, error) {
|
||||
if s == "" {
|
||||
return nil, nil
|
||||
|
|
|
@ -124,7 +124,8 @@
|
|||
|
||||
<details>
|
||||
<summary>Move to another mailbox</summary>
|
||||
<form method="post" action="{{.Message.URL}}/move">
|
||||
<form method="post" action="/message/{{.Mailbox.Name | pathescape}}/move">
|
||||
<input type="hidden" name="uids" value="{{.Message.Uid}}">
|
||||
<div class="form-group">
|
||||
<select class="form-control" name="to" id="move-to">
|
||||
{{range .Mailboxes}}
|
||||
|
@ -140,7 +141,8 @@
|
|||
|
||||
<details>
|
||||
<summary>Delete</summary>
|
||||
<form method="post" action="{{.Message.URL}}/delete">
|
||||
<form method="post" action="/message/{{.Mailbox.Name | pathescape}}/delete">
|
||||
<input type="hidden" name="uids" value="{{.Message.Uid}}">
|
||||
<p>Are you sure?</p>
|
||||
<div class="pull-right">
|
||||
<button class="btn btn-danger">Delete</button>
|
||||
|
@ -151,7 +153,8 @@
|
|||
{{if .Flags}}
|
||||
<details>
|
||||
<summary>Edit flags</summary>
|
||||
<form method="post" action="{{.Message.URL}}/flag">
|
||||
<form method="post" action="/message/{{.Mailbox.Name | pathescape}}/flag">
|
||||
<input type="hidden" name="uids" value="{{.Message.Uid}}">
|
||||
<div class="form-group">
|
||||
{{range $name, $has := .Flags}}
|
||||
{{if ismutableflag $name}}
|
||||
|
|
Loading…
Reference in a new issue