mirror of
https://github.com/axllent/mailpit.git
synced 2025-01-24 03:47:38 +02:00
Merge branch 'release/v1.6.3'
This commit is contained in:
commit
9ae9104ca3
@ -2,6 +2,12 @@
|
||||
|
||||
Notable changes to Mailpit will be documented in this file.
|
||||
|
||||
## [v1.6.3]
|
||||
|
||||
### Feature
|
||||
- Display clickable toast notifications for new messages
|
||||
|
||||
|
||||
## [v1.6.2]
|
||||
|
||||
### Bugfix
|
||||
|
@ -3,6 +3,7 @@ import commonMixins from './mixins.js';
|
||||
import Message from './templates/Message.vue';
|
||||
import MessageSummary from './templates/MessageSummary.vue';
|
||||
import MessageRelease from './templates/MessageRelease.vue';
|
||||
import MessageToast from './templates/MessageToast.vue';
|
||||
import moment from 'moment';
|
||||
import Tinycon from 'tinycon';
|
||||
|
||||
@ -12,7 +13,8 @@ export default {
|
||||
components: {
|
||||
Message,
|
||||
MessageSummary,
|
||||
MessageRelease
|
||||
MessageRelease,
|
||||
MessageToast
|
||||
},
|
||||
|
||||
data() {
|
||||
@ -41,6 +43,7 @@ export default {
|
||||
lastLoaded: false,
|
||||
relayConfig: {},
|
||||
releaseAddresses: false,
|
||||
toastMessage: false,
|
||||
}
|
||||
},
|
||||
|
||||
@ -205,6 +208,7 @@ export default {
|
||||
let self = this;
|
||||
self.selected = [];
|
||||
self.releaseAddresses = false;
|
||||
self.toastMessage = false;
|
||||
self.existingTags = JSON.parse(JSON.stringify(self.tags));
|
||||
|
||||
let uri = 'api/v1/message/' + self.currentPath
|
||||
@ -396,10 +400,16 @@ export default {
|
||||
if (response.Type == "new" && response.Data) {
|
||||
if (!self.searching) {
|
||||
if (self.start < 1) {
|
||||
// first page
|
||||
self.items.unshift(response.Data);
|
||||
if (self.items.length > self.limit) {
|
||||
self.items.pop();
|
||||
}
|
||||
|
||||
// first message was open, set messagePrev
|
||||
if (!self.messagePrev) {
|
||||
self.messagePrev = response.Data.ID;
|
||||
}
|
||||
} else {
|
||||
self.start++;
|
||||
}
|
||||
@ -416,6 +426,7 @@ export default {
|
||||
|
||||
let from = response.Data.From != null ? response.Data.From.Address : '[unknown]';
|
||||
self.browserNotify("New mail from: " + from, response.Data.Subject);
|
||||
self.setMessageToast(response.Data);
|
||||
} else if (response.Type == "prune") {
|
||||
// messages have been deleted, reload messages to adjust
|
||||
self.scrollInPlace = true;
|
||||
@ -591,6 +602,18 @@ export default {
|
||||
document.querySelector('#ReleaseModal input[role="combobox"]').focus()
|
||||
}, 500);
|
||||
}, 300);
|
||||
},
|
||||
|
||||
setMessageToast: function (m) {
|
||||
if (this.toastMessage) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.toastMessage = m;
|
||||
},
|
||||
|
||||
clearMessageToast: function () {
|
||||
this.toastMessage = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1014,4 +1037,6 @@ export default {
|
||||
<MessageRelease v-if="releaseAddresses" :message="message" :relayConfig="relayConfig"
|
||||
:releaseAddresses="releaseAddresses"></MessageRelease>
|
||||
</div>
|
||||
|
||||
<MessageToast v-if="toastMessage" :message="toastMessage" @clearMessageToast="clearMessageToast"></MessageToast>
|
||||
</template>
|
||||
|
2
server/ui-src/assets/bootstrap.scss
vendored
2
server/ui-src/assets/bootstrap.scss
vendored
@ -32,7 +32,7 @@
|
||||
// @import "../../../node_modules/bootstrap/scss/progress";
|
||||
@import "../../../node_modules/bootstrap/scss/list-group";
|
||||
@import "../../../node_modules/bootstrap/scss/close";
|
||||
// @import "../../../node_modules/bootstrap/scss/toasts";
|
||||
@import "../../../node_modules/bootstrap/scss/toasts";
|
||||
@import "../../../node_modules/bootstrap/scss/modal";
|
||||
// @import "../../../node_modules/bootstrap/scss/tooltip";
|
||||
// @import "../../../node_modules/bootstrap/scss/popover";
|
||||
|
44
server/ui-src/templates/MessageToast.vue
Normal file
44
server/ui-src/templates/MessageToast.vue
Normal file
@ -0,0 +1,44 @@
|
||||
<script>
|
||||
import { Toast } from 'bootstrap';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
message: Object
|
||||
},
|
||||
|
||||
mounted() {
|
||||
let self = this;
|
||||
let el = document.getElementById('messageToast');
|
||||
if (el) {
|
||||
el.addEventListener('hidden.bs.toast', () => {
|
||||
self.$emit("clearMessageToast");
|
||||
})
|
||||
|
||||
let b = Toast.getOrCreateInstance(el);
|
||||
b.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="toast-container position-fixed bottom-0 end-0 p-3">
|
||||
<div id="messageToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
|
||||
<div class="toast-header">
|
||||
<i class="bi bi-envelope-exclamation-fill me-2"></i>
|
||||
<strong class="me-auto"><a :href="'#' + message.ID">New message</a></strong>
|
||||
<small class="text-body-secondary">now</small>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
|
||||
</div>
|
||||
|
||||
<div class="toast-body">
|
||||
<div>
|
||||
<a :href="'#' + message.ID" class="d-block text-truncate text-muted">
|
||||
<template v-if="message.Subject != ''">{{ message.Subject }}</template>
|
||||
<template v-else>[ no subject ]</template>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
Loading…
x
Reference in New Issue
Block a user