in site/js/dev/ponymail_email_displays.js [19:210]
function displayEmail(json, id, level) {
// Level indicates the nestedness if threaded view (indentation)
level = level ? level : 1
if (!json.mid && !json.tid) {
alert("404: Could not find this email!")
return
}
if (current_thread_mids[json.mid]) {
return
} else {
current_thread_mids[json.mid] = true
current_email_msgs.push(json)
}
// Save the JSON in our JS array so we don't have to fetch it again later
saved_emails[json.mid] = json
var estyle = ""
last_opened_email = json.mid
// color based on view before or not??
if (localStorageAvailable) {
if (! window.localStorage.getItem("viewed_" + json.mid) ){
//estyle = "linear-gradient(to bottom, rgba(252,255,244,1) 0%,rgba(233,233,206,1) 100%)"
try {
window.localStorage.setItem("viewed_" + json.mid, json.epoch)
} catch(e) {
}
}
if (window.localStorage.getItem("viewed_" + json.mid) && window.localStorage.getItem("viewed_" + json.mid).search("!") == 10){
//estyle = "linear-gradient(to bottom, rgba(252,255,244,1) 0%,rgba(233,233,206,1) 100%)"
var epoch = parseInt(window.localStorage.getItem("viewed_" + json.mid))
try {
window.localStorage.setItem("viewed_" + json.mid, epoch + ":")
} catch(e) {
}
}
}
// Coloring for nested emails
var cols = ['primary', 'success', 'info', 'warning', 'danger']
// Sanitise email ID and find the <div> object it's supposed to go into
var id_sanitised = id.toString().replace(/@<.+>/, "")
var thread = document.getElementById('thread_' + id_sanitised)
if (thread) {
// transform <foo.bar.tld> to foo@bar.tld
var lid = json.list.replace(/[<>]/g, "").replace(/^([^.]+)\./, "$1@")
// Escape email body, convert < to <
var ebody = json.body
if (ebody == null) {ebody = '(null body)'} // temporary hack to deal with broken bodies
ebody = ebody.replace(/</mg, "<")
ebody = "\n" + ebody // add a newline at top
// If we're compacting quotes in the email, let's...do so with some fuzzy logic
if (prefs.compactQuotes == 'yes') {
ebody = ebody.replace(/((?:\r?\n)((on .+ wrote:[\r\n]+)|(sent from my .+)|(>+([ \t]*[^\r\n]*)?\r?\n)+)+)+/mgi, function(inner) {
var rnd = (Math.random() * 100).toString()
inner = inner.replace(/>/g, ">")
var html = "<div class='bs-callout bs-callout-default' style='margin: 3px; padding: 2px;' id='parent_" + rnd + "'>" +
"<img src='" + URL_BASE + "/images/quote.png' title='show/hide original text' onclick='toggleView(\"quote_" + rnd + "\")'/><br/>" +
"<div style='display: none;' id='quote_" + rnd + "'>" + inner + "</div></div>"
return html
})
}
// Turn URLs into <a> tags
ebody = ebody.replace(re_weburl, "<a href='$1'>$1</a>")
// Get theme (social, default etc) if set locally in browser
if (localStorageAvailable) {
var th = window.localStorage.getItem("pm_theme")
if (th) {
prefs.theme = th
}
}
// Social theme rendering
if (prefs.theme && prefs.theme == "social") {
// Date and sender formatting
var sdate = new Date(json.epoch*1000).toLocaleString('en-US', { timeZone: 'UTC', weekday: 'long', year: 'numeric', month: 'long', day: 'numeric', hour: 'numeric', minute: 'numeric' })
var fr = json['from'].replace(/"/g, "").replace(/<.+>/, "").replace(/</g, "<")
thread.style.background = estyle
// Don't indent if we're too deeply nested, it gets weird looking
if (level <= 6) {
thread.style.marginLeft = "40px"
}
thread.style.marginTop = "40px"
thread.innerHTML = "<img src='https://secure.gravatar.com/avatar/" + json['gravatar'] + ".jpg?s=48&r=g&d=mm' style='vertical-align:middle'/> <b>" + fr + "</b> - " + sdate
thread.innerHTML += ' <label class="label label-success" onclick="compose(\'' + json.mid + '\');" style="cursor: pointer; float: right; margin-left: 10px;">Reply</label>'
if (level > 1) {
thread.innerHTML += ' <a href="javascript:void(0);" onclick="rollup(\'' + id_sanitised + '\');"><label class="label label-primary" title="roll up" style="cursor: pointer; float: right; margin-right: 10px;"><span id="rollup_' + id_sanitised + '" class="glyphicon glyphicon-chevron-up"> </span></label></a> '
}
thread.innerHTML += "<br/><br/>"
// Make the colored bar to the left that indicates nest level
var bclass = "bubble-" + cols[parseInt(Math.random() * cols.length - 0.01)]
// append body
thread.innerHTML += "<div class='" + bclass + "' style='padding: 8px; font-family: Hack; word-wrap: normal; white-space: pre-wrap; word-break: normal;'>" + ebody + '</div>'
// Do we have attachments in this email?
if (json.attachments && json.attachments.length > 0) {
thread.innerHTML += "<b>Attachments: </b>"
for (var a in json.attachments) {
// figure out name and size in kb (or bytes if < 1024)
var fd = json.attachments[a]
var size = parseInt(fd.size/1024)
if (size > 0) {
size = size.toLocaleString() + " kb"
} else {
size = fd.size.toLocaleString() + " bytes"
}
thread.innerHTML += "<a href='" + URL_BASE + "/api/email.lua?attachment=true&id=" + json.tid + "&file=" + fd.hash + "'>" + fd.filename.replace(/</g, "<") + "</a> (" + size + ") "
}
thread.innerHTML += "<br/>"
}
// This is for the 'highlight new emails' feature
if (thread.hasAttribute("meme")) {
thread.scrollIntoView()
thread.style.background = "rgba(200,200,255, 0.25)"
}
}
// Default theme
else {
thread.setAttribute("class", "reply bs-callout bs-callout-" + cols[parseInt(Math.random() * cols.length - 0.01)])
thread.style.background = estyle
thread.style.marginTop = "30px"
thread.innerHTML += ' <label class="label label-success" onclick="compose(\'' + json.mid + '\');" style="cursor: pointer; float: right; margin-left: 10px;">Reply</label>'
thread.innerHTML += ' <a href="' + URL_BASE + '/thread.html/'+(pm_config.shortLinks ? shortenID(json.mid) : encodeURIComponent(json.mid))+'"><label class="label label-warning" style="cursor: pointer; float: right;">Permalink</label></a>'
thread.innerHTML += ' <a href="' + URL_BASE + '/api/source.lua/'+encodeURIComponent(json.mid)+'"><label class="label label-danger" style="cursor: pointer; float: right; margin-right: 10px;">View Source</label></a> '
if (level > 1) {
thread.innerHTML += ' <a href="javascript:void(0);" onclick="rollup(\'' + id_sanitised + '\');"><label class="label label-primary" title="roll up" style="cursor: pointer; float: right; margin-right: 10px;"><span id="rollup_' + id_sanitised + '" class="glyphicon glyphicon-chevron-up"> </span></label></a> '
}
thread.innerHTML += "<br/>"
//thread.style.border = "1px dotted #666"
thread.style.padding = "0px"
thread.style.leftpadding = "10px"
thread.style.rightpadding = "0px"
thread.style.fontFamily = "Hack"
var fields = ['From', 'To', 'CC', 'Subject', 'Date']
for (var i in fields) {
var key = fields[i]
if (json[key.toLowerCase()] != undefined && json[key.toLowerCase()].length > 0) {
thread.innerHTML += "<b>" + key + ": </b>" + json[key.toLowerCase()].replace(/</g, "<") + "<br/>"
}
}
if (json.private) {
thread.innerHTML += "<font color='#C00'><b>Private: </b> YES</font><br/>"
if (level == 1) {
thread.style.backgroundImage = "url(/images/private.png)"
}
}
thread.innerHTML += "<b>List: </b><a href='" + URL_BASE + "/list.html?" + lid + "'>" + lid + "</a><br/>"
if (json.attachments && json.attachments.length > 0) {
thread.innerHTML += "<b>Attachments: </b>"
for (var a in json.attachments) {
var fd = json.attachments[a]
var size = parseInt(fd.size/1024)
if (size > 0) {
size = size.toLocaleString() + " kb"
} else {
size = fd.size.toLocaleString() + " bytes"
}
thread.innerHTML += "<a href='" + URL_BASE + "/api/email.lua?attachment=true&id=" + json.tid + "&file=" + fd.hash + "'>" + fd.filename.replace(/</g, "<") + "</a> (" + size + ") "
}
thread.innerHTML += "<br/>"
}
var pv = ""
if (json.private) {
pv = "background: none !important;"
}
thread.innerHTML += "<pre style='color: inherit; padding: 8px; font-family: Hack; word-wrap: normal; white-space: pre-wrap; word-break: normal; " + pv + "'>" + ebody + '</pre>'
// Same as with social theme - "highlight new emails"
if (thread.hasAttribute("meme")) {
thread.scrollIntoView()
thread.style.background = "rgba(200,200,255, 0.25)"
}
}
} else {
alert("Error, " + id + " not found :(")
}
}