mirror of
https://github.com/axllent/mailpit.git
synced 2024-12-30 23:17:59 +02:00
Feature: Mark all messages as read
This commit is contained in:
parent
f260495495
commit
d4cf95363f
@ -218,6 +218,22 @@ func apiUnreadOne(w http.ResponseWriter, r *http.Request) {
|
||||
_, _ = w.Write([]byte("ok"))
|
||||
}
|
||||
|
||||
// Mark single message as unread
|
||||
func apiMarkAllRead(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
|
||||
mailbox := vars["mailbox"]
|
||||
|
||||
err := storage.MarkAllRead(mailbox)
|
||||
if err != nil {
|
||||
httpError(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Add("Content-Type", "text/plain")
|
||||
_, _ = w.Write([]byte("ok"))
|
||||
}
|
||||
|
||||
// Websocket to broadcast changes
|
||||
func apiWebsocket(w http.ResponseWriter, r *http.Request) {
|
||||
websockets.ServeWs(websockets.MessageHub, w, r)
|
||||
|
@ -39,6 +39,7 @@ func Listen() {
|
||||
r.HandleFunc("/api/{mailbox}/search", middleWareFunc(apiSearchMailbox))
|
||||
r.HandleFunc("/api/{mailbox}/delete", middleWareFunc(apiDeleteAll))
|
||||
r.HandleFunc("/api/{mailbox}/events", apiWebsocket)
|
||||
r.HandleFunc("/api/{mailbox}/read", apiMarkAllRead)
|
||||
r.HandleFunc("/api/{mailbox}/{id}/source", middleWareFunc(apiDownloadSource))
|
||||
r.HandleFunc("/api/{mailbox}/{id}/part/{partID}", middleWareFunc(apiDownloadAttachment))
|
||||
r.HandleFunc("/api/{mailbox}/{id}/delete", middleWareFunc(apiDeleteOne))
|
||||
|
@ -198,6 +198,16 @@ export default {
|
||||
});
|
||||
},
|
||||
|
||||
markAllRead: function() {
|
||||
let self = this;
|
||||
let uri = 'api/' + self.mailbox + '/read'
|
||||
self.get(uri, false, function(response) {
|
||||
window.location.hash = "";
|
||||
self.scrollInPlace = true;
|
||||
self.loadMessages();
|
||||
});
|
||||
},
|
||||
|
||||
// websocket connect
|
||||
connect: function () {
|
||||
let wsproto = location.protocol == 'https:' ? 'wss' : 'ws';
|
||||
@ -360,15 +370,15 @@ export default {
|
||||
<div class="row flex-fill" style="min-height:0">
|
||||
<div class="d-none d-md-block col-lg-2 col-md-3 mh-100 position-relative" style="overflow-y: auto;">
|
||||
<ul class="list-unstyled mt-3 mb-5">
|
||||
<li v-if="isConnected" title="Messages will auto-load">
|
||||
<li v-if="isConnected" title="Messages will auto-load" class="mb-2">
|
||||
<i class="bi bi-power text-success"></i>
|
||||
Connected
|
||||
</li>
|
||||
<li v-else title="You need to manually refresh your mailbox">
|
||||
<li v-else title="You need to manually refresh your mailbox" class="mb-3">
|
||||
<i class="bi bi-power text-danger"></i>
|
||||
Disconnected
|
||||
</li>
|
||||
<li class="mt-3">
|
||||
<li class="mb-5">
|
||||
<a class="position-relative ps-0" href="#" v-on:click="reloadMessages">
|
||||
<i class="bi bi-envelope me-1" v-if="isConnected"></i>
|
||||
<i class="bi bi-arrow-clockwise me-1" v-else></i>
|
||||
@ -378,20 +388,26 @@ export default {
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mt-3">
|
||||
<a v-if="total" href="#" data-bs-toggle="modal" data-bs-target="#DeleteAllModal">
|
||||
<li class="my-3" v-if="unread">
|
||||
<a href="#" data-bs-toggle="modal" data-bs-target="#MarkAllReadModal">
|
||||
<i class="bi bi-check2-square"></i>
|
||||
Mark all read
|
||||
</a>
|
||||
</li>
|
||||
<li class="my-3" v-if="total">
|
||||
<a href="#" data-bs-toggle="modal" data-bs-target="#DeleteAllModal">
|
||||
<i class="bi bi-trash-fill me-1 text-danger"></i>
|
||||
Delete all
|
||||
</a>
|
||||
</li>
|
||||
<li class="mt-3" v-if="notificationsSupported && !notificationsEnabled">
|
||||
<li class="my-3" v-if="notificationsSupported && !notificationsEnabled">
|
||||
<a href="#" data-bs-toggle="modal" data-bs-target="#EnableNotificationsModal" title="Enable browser notifications">
|
||||
<i class="bi bi-bell"></i>
|
||||
Enable alerts
|
||||
</a>
|
||||
</li>
|
||||
<li class="mt-5 position-fixed bottom-0">
|
||||
<a href="https://github.com/axllent/mailpit" target="_blank" class="text-muted w-100 d-block bg-white py-2">
|
||||
<a href="https://github.com/axllent/mailpit" target="_blank" class="text-muted w-100 d-block bg-white my-3">
|
||||
<i class="bi bi-github"></i>
|
||||
GitHub
|
||||
</a>
|
||||
@ -435,7 +451,7 @@ export default {
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div v-else class="text-muted py-3">No messages</div>
|
||||
<div v-else class="text-muted my-3">No messages</div>
|
||||
</div>
|
||||
|
||||
<Message v-if="message" :message="message" :mailbox="mailbox"></Message>
|
||||
@ -468,6 +484,25 @@ export default {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal -->
|
||||
<div class="modal fade" id="MarkAllReadModal" tabindex="-1" aria-labelledby="MarkAllReadModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="MarkAllReadModalLabel">Mark all messages as read?</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
This will mark {{ formatNumber(unread) }} message<span v-if="unread > 1">s</span> as read.
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||||
<button type="button" class="btn btn-primary" data-bs-dismiss="modal" v-on:click="markAllRead">Confirm</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal -->
|
||||
<div class="modal fade" id="EnableNotificationsModal" tabindex="-1" aria-labelledby="EnableNotificationsModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg">
|
||||
|
@ -574,3 +574,38 @@ func DeleteAllMessages(mailbox string) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarkAllRead will mark every unread message in a mailbox as read
|
||||
func MarkAllRead(mailbox string) error {
|
||||
mailbox = sanitizeMailboxName(mailbox)
|
||||
|
||||
totalStart := time.Now()
|
||||
|
||||
q, err := db.FindAll(clover.NewQuery(mailbox).
|
||||
Where(clover.Field("Read").IsFalse()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
total := len(q)
|
||||
|
||||
updates := make(map[string]interface{})
|
||||
updates["Read"] = true
|
||||
|
||||
for _, m := range q {
|
||||
if err := db.UpdateById(mailbox, m.ObjectId(), updates); err != nil {
|
||||
logger.Log().Error(err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := statsRefresh(mailbox); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
elapsed := time.Since(totalStart)
|
||||
|
||||
logger.Log().Debugf("[db] marked %d messages in %s as read in %s", total, mailbox, elapsed)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user