1
0
mirror of https://github.com/axllent/mailpit.git synced 2025-02-05 13:14:57 +02:00

Code cleanup

This commit is contained in:
Ralph Slooten 2023-06-30 22:42:33 +12:00
parent 7748846b88
commit 48f22cca1f
3 changed files with 298 additions and 298 deletions

View File

@ -52,55 +52,55 @@ export default {
watch: {
currentPath(v, old) {
if (v && v.match(/^[a-z0-9]+-[a-z0-9]+-[a-z0-9]+-[a-z0-9]+-[a-z0-9]+$/)) {
this.openMessage();
this.openMessage()
} else {
this.message = false;
this.message = false
}
},
unread(v, old) {
if (v == this.tcStatus) {
return;
return
}
this.tcStatus = v;
this.tcStatus = v
if (v == 0) {
Tinycon.reset();
Tinycon.reset()
} else {
Tinycon.setBubble(v);
Tinycon.setBubble(v)
}
}
},
computed: {
canPrev: function () {
return this.start > 0;
return this.start > 0
},
canNext: function () {
return this.total > (this.start + this.count);
return this.total > (this.start + this.count)
},
unreadInSearch: function () {
if (!this.searching) {
return false;
return false
}
return this.items.filter(i => !i.Read).length;
return this.items.filter(i => !i.Read).length
}
},
mounted() {
this.currentPath = window.location.hash.slice(1);
this.currentPath = window.location.hash.slice(1)
window.addEventListener('hashchange', () => {
this.currentPath = window.location.hash.slice(1);
});
this.currentPath = window.location.hash.slice(1)
})
this.notificationsSupported = window.isSecureContext
&& ("Notification" in window && Notification.permission !== "denied");
this.notificationsEnabled = this.notificationsSupported && Notification.permission == "granted";
&& ("Notification" in window && Notification.permission !== "denied")
this.notificationsEnabled = this.notificationsSupported && Notification.permission == "granted"
Tinycon.setOptions({
height: 11,
background: '#dd0000',
fallback: false
});
})
moment.updateLocale('en', {
relativeTime: {
@ -121,11 +121,11 @@ export default {
y: "a year",
yy: "%d years"
}
});
})
this.connect();
this.getUISettings();
this.loadMessages();
this.connect()
this.getUISettings()
this.loadMessages()
},
methods: {
@ -133,143 +133,143 @@ export default {
let now = Date.now()
// prevent double loading when UI loads & websocket connects
if (this.lastLoaded && now - this.lastLoaded < 250) {
return;
return
}
if (this.start == 0) {
this.lastLoaded = now;
this.lastLoaded = now
}
let self = this;
let params = {};
self.selected = [];
let self = this
let params = {}
self.selected = []
let uri = 'api/v1/messages';
let uri = 'api/v1/messages'
if (self.search) {
self.searching = true;
self.items = [];
self.searching = true
self.items = []
uri = 'api/v1/search'
self.start = 0; // search is displayed on one page
params['query'] = self.search;
params['limit'] = 200;
self.start = 0 // search is displayed on one page
params['query'] = self.search
params['limit'] = 200
} else {
self.searching = false;
params['limit'] = self.limit;
self.searching = false
params['limit'] = self.limit
if (self.start > 0) {
params['start'] = self.start;
params['start'] = self.start
}
}
self.get(uri, params, function (response) {
self.total = response.data.total;
self.unread = response.data.unread;
self.count = response.data.count;
self.start = response.data.start;
self.items = response.data.messages;
self.tags = response.data.tags;
self.existingTags = JSON.parse(JSON.stringify(self.tags));
self.total = response.data.total
self.unread = response.data.unread
self.count = response.data.count
self.start = response.data.start
self.items = response.data.messages
self.tags = response.data.tags
self.existingTags = JSON.parse(JSON.stringify(self.tags))
// if pagination > 0 && results == 0 reload first page (prune)
if (response.data.count == 0 && response.data.start > 0) {
self.start = 0;
return self.loadMessages();
self.start = 0
return self.loadMessages()
}
if (!self.scrollInPlace) {
let mp = document.getElementById('message-page');
let mp = document.getElementById('message-page')
if (mp) {
mp.scrollTop = 0;
mp.scrollTop = 0
}
}
self.scrollInPlace = false;
});
self.scrollInPlace = false
})
},
getUISettings: function () {
let self = this;
let self = this
self.get('api/v1/webui', null, function (response) {
self.relayConfig = response.data;
});
self.relayConfig = response.data
})
},
doSearch: function (e) {
e.preventDefault();
this.loadMessages();
e.preventDefault()
this.loadMessages()
},
tagSearch: function (e, tag) {
e.preventDefault();
e.preventDefault()
if (tag.match(/ /)) {
tag = '"' + tag + '"';
tag = '"' + tag + '"'
}
this.search = 'tag:' + tag;
window.location.hash = "";
this.loadMessages();
this.search = 'tag:' + tag
window.location.hash = ""
this.loadMessages()
},
resetSearch: function (e) {
e.preventDefault();
this.search = '';
this.scrollInPlace = true;
this.loadMessages();
e.preventDefault()
this.search = ''
this.scrollInPlace = true
this.loadMessages()
},
reloadMessages: function () {
this.search = "";
this.start = 0;
this.loadMessages();
this.search = ""
this.start = 0
this.loadMessages()
},
viewNext: function () {
this.start = parseInt(this.start, 10) + parseInt(this.limit, 10);
this.loadMessages();
this.start = parseInt(this.start, 10) + parseInt(this.limit, 10)
this.loadMessages()
},
viewPrev: function () {
let s = this.start - this.limit;
let s = this.start - this.limit
if (s < 0) {
s = 0;
s = 0
}
this.start = s;
this.loadMessages();
this.start = s
this.loadMessages()
},
openMessage: function (id) {
let self = this;
self.selected = [];
self.releaseAddresses = false;
self.toastMessage = false;
self.existingTags = JSON.parse(JSON.stringify(self.tags));
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
self.get(uri, false, function (response) {
for (let i in self.items) {
if (self.items[i].ID == self.currentPath) {
if (!self.items[i].Read) {
self.items[i].Read = true;
self.unread--;
self.items[i].Read = true
self.unread--
}
}
}
let d = response.data;
let d = response.data
// replace inline images embedded as inline attachments
if (d.HTML && d.Inline) {
for (let i in d.Inline) {
let a = d.Inline[i];
let a = d.Inline[i]
if (a.ContentID != '') {
d.HTML = d.HTML.replace(
new RegExp('(=["\']?)(cid:' + a.ContentID + ')(["|\'|\\s|\\/|>|;])', 'g'),
'$1' + window.location.origin + window.location.pathname + 'api/v1/message/' + d.ID + '/part/' + a.PartID + '$3'
);
)
}
if (a.FileName.match(/^[a-zA-Z0-9\_\-\.]+$/)) {
// some old email clients use the filename
d.HTML = d.HTML.replace(
new RegExp('(=["\']?)(' + a.FileName + ')(["|\'|\\s|\\/|>|;])', 'g'),
'$1' + window.location.origin + window.location.pathname + 'api/v1/message/' + d.ID + '/part/' + a.PartID + '$3'
);
)
}
}
}
@ -277,381 +277,381 @@ export default {
// replace inline images embedded as regular attachments
if (d.HTML && d.Attachments) {
for (let i in d.Attachments) {
let a = d.Attachments[i];
let a = d.Attachments[i]
if (a.ContentID != '') {
d.HTML = d.HTML.replace(
new RegExp('(=["\']?)(cid:' + a.ContentID + ')(["|\'|\\s|\\/|>|;])', 'g'),
'$1' + window.location.origin + window.location.pathname + 'api/v1/message/' + d.ID + '/part/' + a.PartID + '$3'
);
)
}
if (a.FileName.match(/^[a-zA-Z0-9\_\-\.]+$/)) {
// some old email clients use the filename
d.HTML = d.HTML.replace(
new RegExp('(=["\']?)(' + a.FileName + ')(["|\'|\\s|\\/|>|;])', 'g'),
'$1' + window.location.origin + window.location.pathname + 'api/v1/message/' + d.ID + '/part/' + a.PartID + '$3'
);
)
}
}
}
self.message = d;
self.message = d
// generate the prev/next links based on current message list
self.messagePrev = false;
self.messageNext = false;
let found = false;
self.messagePrev = false
self.messageNext = false
let found = false
for (let i in self.items) {
if (self.items[i].ID == self.message.ID) {
found = true;
found = true
} else if (found && !self.messageNext) {
self.messageNext = self.items[i].ID;
break;
self.messageNext = self.items[i].ID
break
} else {
self.messagePrev = self.items[i].ID;
self.messagePrev = self.items[i].ID
}
}
});
})
},
// universal handler to delete current or selected messages
deleteMessages: function () {
let ids = [];
let self = this;
let ids = []
let self = this
if (self.message) {
ids.push(self.message.ID);
ids.push(self.message.ID)
} else {
ids = JSON.parse(JSON.stringify(self.selected));
ids = JSON.parse(JSON.stringify(self.selected))
}
if (!ids.length) {
return false;
return false
}
let uri = 'api/v1/messages';
let uri = 'api/v1/messages'
self.delete(uri, { 'ids': ids }, function (response) {
window.location.hash = "";
self.scrollInPlace = true;
self.loadMessages();
});
window.location.hash = ""
self.scrollInPlace = true
self.loadMessages()
})
},
// delete messages displayed in current search
deleteSearch: function () {
let ids = this.items.map(item => item.ID);
let ids = this.items.map(item => item.ID)
if (!ids.length) {
return false;
return false
}
let self = this;
let uri = 'api/v1/messages';
let self = this
let uri = 'api/v1/messages'
self.delete(uri, { 'ids': ids }, function (response) {
window.location.hash = "";
self.scrollInPlace = true;
self.loadMessages();
});
window.location.hash = ""
self.scrollInPlace = true
self.loadMessages()
})
},
// delete all messages from mailbox
deleteAll: function () {
let self = this;
let uri = 'api/v1/messages';
let self = this
let uri = 'api/v1/messages'
self.delete(uri, false, function (response) {
window.location.hash = "";
self.reloadMessages();
});
window.location.hash = ""
self.reloadMessages()
})
},
// mark current message as read
markUnread: function () {
let self = this;
let self = this
if (!self.message) {
return false;
return false
}
let uri = 'api/v1/messages';
let uri = 'api/v1/messages'
self.put(uri, { 'read': false, 'ids': [self.message.ID] }, function (response) {
window.location.hash = "";
self.scrollInPlace = true;
self.loadMessages();
});
window.location.hash = ""
self.scrollInPlace = true
self.loadMessages()
})
},
// mark all messages in mailbox as read
markAllRead: function () {
let self = this;
let self = this
let uri = 'api/v1/messages'
self.put(uri, { 'read': true }, function (response) {
window.location.hash = "";
self.scrollInPlace = true;
self.loadMessages();
});
window.location.hash = ""
self.scrollInPlace = true
self.loadMessages()
})
},
// mark messages in current search as read
markSearchRead: function () {
let ids = this.items.map(item => item.ID);
let ids = this.items.map(item => item.ID)
if (!ids.length) {
return false;
return false
}
let self = this;
let uri = 'api/v1/messages';
let self = this
let uri = 'api/v1/messages'
self.put(uri, { 'read': true, 'ids': ids }, function (response) {
window.location.hash = "";
self.scrollInPlace = true;
self.loadMessages();
});
window.location.hash = ""
self.scrollInPlace = true
self.loadMessages()
})
},
// mark selected messages as read
markSelectedRead: function () {
let self = this;
let self = this
if (!self.selected.length) {
return false;
return false
}
let uri = 'api/v1/messages';
let uri = 'api/v1/messages'
self.put(uri, { 'read': true, 'ids': self.selected }, function (response) {
window.location.hash = "";
self.scrollInPlace = true;
self.loadMessages();
});
window.location.hash = ""
self.scrollInPlace = true
self.loadMessages()
})
},
// mark selected messages as unread
markSelectedUnread: function () {
let self = this;
let self = this
if (!self.selected.length) {
return false;
return false
}
let uri = 'api/v1/messages';
let uri = 'api/v1/messages'
self.put(uri, { 'read': false, 'ids': self.selected }, function (response) {
window.location.hash = "";
self.scrollInPlace = true;
self.loadMessages();
});
window.location.hash = ""
self.scrollInPlace = true
self.loadMessages()
})
},
// test if any selected emails are unread
selectedHasUnread: function () {
if (!this.selected.length) {
return false;
return false
}
for (let i in this.items) {
if (this.isSelected(this.items[i].ID) && !this.items[i].Read) {
return true;
return true
}
}
return false;
return false
},
// test of any selected emails are read
selectedHasRead: function () {
if (!this.selected.length) {
return false;
return false
}
for (let i in this.items) {
if (this.isSelected(this.items[i].ID) && this.items[i].Read) {
return true;
return true
}
}
return false;
return false
},
// websocket connect
connect: function () {
let wsproto = location.protocol == 'https:' ? 'wss' : 'ws';
let wsproto = location.protocol == 'https:' ? 'wss' : 'ws'
let ws = new WebSocket(
wsproto + "://" + document.location.host + document.location.pathname + "api/events"
);
let self = this;
)
let self = this
ws.onmessage = function (e) {
let response = JSON.parse(e.data);
let response = JSON.parse(e.data)
if (!response) {
return;
return
}
// new messages
if (response.Type == "new" && response.Data) {
if (!self.searching) {
if (self.start < 1) {
// first page
self.items.unshift(response.Data);
self.items.unshift(response.Data)
if (self.items.length > self.limit) {
self.items.pop();
self.items.pop()
}
// first message was open, set messagePrev
if (!self.messagePrev) {
self.messagePrev = response.Data.ID;
self.messagePrev = response.Data.ID
}
} else {
self.start++;
self.start++
}
}
self.total++;
self.unread++;
self.total++
self.unread++
for (let i in response.Data.Tags) {
if (self.tags.indexOf(response.Data.Tags[i]) < 0) {
self.tags.push(response.Data.Tags[i]);
self.tags.sort();
self.tags.push(response.Data.Tags[i])
self.tags.sort()
}
}
let from = response.Data.From != null ? response.Data.From.Address : '[unknown]';
self.browserNotify("New mail from: " + from, response.Data.Subject);
self.setMessageToast(response.Data);
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;
self.loadMessages();
self.scrollInPlace = true
self.loadMessages()
}
}
ws.onopen = function () {
self.isConnected = true;
self.loadMessages();
self.isConnected = true
self.loadMessages()
}
ws.onclose = function (e) {
self.isConnected = false;
self.isConnected = false
setTimeout(function () {
self.connect(); // reconnect
}, 1000);
self.connect() // reconnect
}, 1000)
}
ws.onerror = function (err) {
ws.close();
ws.close()
}
},
getPrimaryEmailTo: function (message) {
for (let i in message.To) {
return message.To[i].Address;
return message.To[i].Address
}
return '[ Undisclosed recipients ]';
return '[ Undisclosed recipients ]'
},
getRelativeCreated: function (message) {
let d = new Date(message.Created)
return moment(d).fromNow().toString();
return moment(d).fromNow().toString()
},
browserNotify: function (title, message) {
if (!("Notification" in window)) {
return;
return
}
if (Notification.permission === "granted") {
let b = message.Subject;
let b = message.Subject
let options = {
body: message,
icon: 'notification.png'
}
new Notification(title, options);
new Notification(title, options)
}
},
requestNotifications: function () {
// check if the browser supports notifications
if (!("Notification" in window)) {
alert("This browser does not support desktop notification");
alert("This browser does not support desktop notification")
}
// we need to ask the user for permission
else if (Notification.permission !== "denied") {
let self = this;
let self = this
Notification.requestPermission().then(function (permission) {
// if the user accepts, let's create a notification
if (permission === "granted") {
self.browserNotify("Notifications enabled", "You will receive notifications when new mails are received.");
self.notificationsEnabled = true;
self.browserNotify("Notifications enabled", "You will receive notifications when new mails are received.")
self.notificationsEnabled = true
}
});
})
}
},
toggleSelected: function (e, id) {
e.preventDefault();
e.preventDefault()
if (this.isSelected(id)) {
this.selected = this.selected.filter(function (ele) {
return ele != id;
});
return ele != id
})
} else {
this.selected.push(id);
this.selected.push(id)
}
},
selectRange: function (e, id) {
e.preventDefault();
e.preventDefault()
let selecting = false;
let lastSelected = this.selected.length > 0 && this.selected[this.selected.length - 1];
let selecting = false
let lastSelected = this.selected.length > 0 && this.selected[this.selected.length - 1]
if (lastSelected == id) {
this.selected = this.selected.filter(function (ele) {
return ele != id;
});
return;
return ele != id
})
return
}
if (lastSelected === false) {
this.selected.push(id);
return;
this.selected.push(id)
return
}
for (let d of this.items) {
if (selecting) {
if (!this.isSelected(d.ID)) {
this.selected.push(d.ID);
this.selected.push(d.ID)
}
if (d.ID == lastSelected || d.ID == id) {
// reached backwards select
break;
break
}
} else if (d.ID == id || d.ID == lastSelected) {
if (!this.isSelected(d.ID)) {
this.selected.push(d.ID);
this.selected.push(d.ID)
}
selecting = true;
selecting = true
}
}
},
isSelected: function (id) {
return this.selected.indexOf(id) != -1;
return this.selected.indexOf(id) != -1
},
inSearch: function (tag) {
tag = tag.toLowerCase();
tag = tag.toLowerCase()
if (tag.match(/ /)) {
tag = '"' + tag + '"';
tag = '"' + tag + '"'
}
return this.search.toLowerCase().indexOf('tag:' + tag) > -1;
return this.search.toLowerCase().indexOf('tag:' + tag) > -1
},
loadInfo: function (e) {
e.preventDefault();
let self = this;
e.preventDefault()
let self = this
self.get('api/v1/info', false, function (response) {
self.appInfo = response.data;
self.modal('AppInfoModal').show();
});
self.appInfo = response.data
self.modal('AppInfoModal').show()
})
},
downloadMessageBody: function (str, ext) {
let dl = document.createElement('a');
dl.href = "data:text/plain," + encodeURIComponent(str);
dl.target = '_blank';
dl.download = this.message.ID + '.' + ext;
dl.click();
let dl = document.createElement('a')
dl.href = "data:text/plain," + encodeURIComponent(str)
dl.target = '_blank'
dl.download = this.message.ID + '.' + ext
dl.click()
},
initReleaseModal: function () {
this.releaseAddresses = false;
let addresses = [];
this.releaseAddresses = false
let addresses = []
for (let i in this.message.To) {
addresses.push(this.message.To[i].Address)
}
@ -663,31 +663,31 @@ export default {
}
// include only unique email addresses, regardless of casing
let uAddresses = new Map(addresses.map(a => [a.toLowerCase(), a]));
this.releaseAddresses = [...uAddresses.values()];
let uAddresses = new Map(addresses.map(a => [a.toLowerCase(), a]))
this.releaseAddresses = [...uAddresses.values()]
let self = this;
let self = this
window.setTimeout(function () {
// delay to allow elements to load
self.modal('ReleaseModal').show();
self.modal('ReleaseModal').show()
window.setTimeout(function () {
document.querySelector('#ReleaseModal input[role="combobox"]').focus()
}, 500);
}, 300);
}, 500)
}, 300)
},
setMessageToast: function (m) {
// don't display if browser notifications are enabled, or a toast is already displayed
if (this.notificationsEnabled || this.toastMessage) {
return;
return
}
this.toastMessage = m;
this.toastMessage = m
},
clearMessageToast: function () {
this.toastMessage = false;
this.toastMessage = false
}
}
}

View File

@ -1,10 +1,10 @@
<script>
import commonMixins from '../mixins.js';
import Prism from "prismjs";
import Tags from "bootstrap5-tags";
import Attachments from './Attachments.vue';
import Headers from './Headers.vue';
import commonMixins from '../mixins.js'
import Prism from "prismjs"
import Tags from "bootstrap5-tags"
import Attachments from './Attachments.vue'
import Headers from './Headers.vue'
export default {
props: {
@ -14,7 +14,7 @@ export default {
components: {
Attachments,
Headers
Headers,
},
mixins: [commonMixins],
@ -41,20 +41,20 @@ export default {
watch: {
message: {
handler() {
let self = this;
self.showTags = false;
self.messageTags = self.message.Tags;
self.allTags = self.existingTags;
self.loadHeaders = false;
let self = this
self.showTags = false
self.messageTags = self.message.Tags
self.allTags = self.existingTags
self.loadHeaders = false
self.scaleHTMLPreview = 'display';// default view
// delay to select first tab and add HTML highlighting (prev/next)
self.$nextTick(function () {
self.renderUI();
self.showTags = true;
self.renderUI()
self.showTags = true
self.$nextTick(function () {
Tags.init("select[multiple]");
});
});
Tags.init("select[multiple]")
})
})
},
// force eager callback execution
immediate: true
@ -62,82 +62,82 @@ export default {
messageTags() {
// save changed to tags
if (this.showTags) {
this.saveTags();
this.saveTags()
}
},
scaleHTMLPreview() {
if (this.scaleHTMLPreview == 'display') {
let self = this;
let self = this
window.setTimeout(function () {
self.resizeIframes();
}, 500);
self.resizeIframes()
}, 500)
}
}
},
mounted() {
let self = this;
self.showTags = false;
self.allTags = self.existingTags;
window.addEventListener("resize", self.resizeIframes);
self.renderUI();
let self = this
self.showTags = false
self.allTags = self.existingTags
window.addEventListener("resize", self.resizeIframes)
self.renderUI()
let headersTab = document.getElementById('nav-headers-tab');
let headersTab = document.getElementById('nav-headers-tab')
headersTab.addEventListener('shown.bs.tab', function (event) {
self.loadHeaders = true;
});
self.loadHeaders = true
})
let rawTab = document.getElementById('nav-raw-tab');
let rawTab = document.getElementById('nav-raw-tab')
rawTab.addEventListener('shown.bs.tab', function (event) {
self.srcURI = 'api/v1/message/' + self.message.ID + '/raw';
self.resizeIframes();
});
self.srcURI = 'api/v1/message/' + self.message.ID + '/raw'
self.resizeIframes()
})
self.showTags = true;
self.showTags = true
self.$nextTick(function () {
Tags.init("select[multiple]");
});
Tags.init("select[multiple]")
})
},
unmounted: function () {
window.removeEventListener("resize", this.resizeIframes);
window.removeEventListener("resize", this.resizeIframes)
},
methods: {
renderUI: function () {
let self = this;
let self = this
// click the first non-disabled tab
document.querySelector('#nav-tab button:not([disabled])').click();
document.activeElement.blur(); // blur focus
document.getElementById('message-view').scrollTop = 0;
document.querySelector('#nav-tab button:not([disabled])').click()
document.activeElement.blur() // blur focus
document.getElementById('message-view').scrollTop = 0
// delay 0.2s until vue has rendered the iframe content
window.setTimeout(function () {
let p = document.getElementById('preview-html');
let p = document.getElementById('preview-html')
if (p) {
// make links open in new window
let anchorEls = p.contentWindow.document.body.querySelectorAll('a');
let anchorEls = p.contentWindow.document.body.querySelectorAll('a')
for (var i = 0; i < anchorEls.length; i++) {
let anchorEl = anchorEls[i];
let href = anchorEl.getAttribute('href');
let anchorEl = anchorEls[i]
let href = anchorEl.getAttribute('href')
if (href && href.match(/^http/)) {
anchorEl.setAttribute('target', '_blank');
anchorEl.setAttribute('target', '_blank')
}
}
self.resizeIframes();
self.resizeIframes()
}
}, 200);
}, 200)
// html highlighting
window.Prism = window.Prism || {};
window.Prism.manual = true;
Prism.highlightAll();
window.Prism = window.Prism || {}
window.Prism.manual = true
Prism.highlightAll()
},
resizeIframe: function (el) {
let i = el.target;
i.style.height = i.contentWindow.document.body.scrollHeight + 50 + 'px';
let i = el.target
i.style.height = i.contentWindow.document.body.scrollHeight + 50 + 'px'
},
resizeIframes: function () {
@ -167,7 +167,7 @@ export default {
},
saveTags: function () {
let self = this;
let self = this
var data = {
ids: [this.message.ID],
@ -175,9 +175,9 @@ export default {
}
self.put('api/v1/tags', data, function (response) {
self.scrollInPlace = true;
self.$emit('loadMessages');
});
self.scrollInPlace = true
self.$emit('loadMessages')
})
},
// Convert plain text to HTML including anchor links

View File

@ -1,7 +1,7 @@
<script>
import Tags from "bootstrap5-tags";
import commonMixins from '../mixins.js';
import Tags from "bootstrap5-tags"
import commonMixins from '../mixins.js'
export default {
props: {
@ -19,19 +19,19 @@ export default {
mixins: [commonMixins],
mounted() {
this.addresses = JSON.parse(JSON.stringify(this.releaseAddresses));
this.addresses = JSON.parse(JSON.stringify(this.releaseAddresses))
this.$nextTick(function () {
Tags.init("select[multiple]");
});
Tags.init("select[multiple]")
})
},
methods: {
releaseMessage: function () {
let self = this;
let self = this
// set timeout to allow for user clicking send before the tag filter has applied the tag
window.setTimeout(function () {
if (!self.addresses.length) {
return false;
return false
}
let data = {
@ -39,9 +39,9 @@ export default {
}
self.post('api/v1/message/' + self.message.ID + '/release', data, function (response) {
self.modal("ReleaseModal").hide();
});
}, 100);
self.modal("ReleaseModal").hide()
})
}, 100)
}
}
}