/* * MIT License * * Copyright (c) 2020 Alexey Edelev * * This file is part of gostfix project https://git.semlanik.org/semlanik/gostfix * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * software and associated documentation files (the "Software"), to deal in the Software * without restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be included in all copies * or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ var currentFolder = "" var currentPage = 0 var currentMail = "" var updateTimerId = null var updateInterval = 50000 var mailbox = "" var pageMax = 10 const mailboxRegex = /^(\/m\d+)/g var folders = new Array() $(window).click(function(e){ var target = $(e.target) var isDropDown = false for (var i = 0; i < target.parents().length; i++) { isDropDown = target.parents()[i].classList.contains("dropbtn") if (isDropDown) { break } } if (!e.target.matches('.dropbtn') && !isDropDown) { $(".dropdown-content").hide() } }) $(document).ready(function(){ $.ajaxSetup({ global: false, type: "POST" }) urlPaths = mailboxRegex.exec($(location).attr('pathname')) if (urlPaths != null && urlPaths.length === 2) { mailbox = urlPaths[0] } else { mailbox = "" } $(window).bind('hashchange', onHashChanged) onHashChanged() loadFolders() loadStatusLine() if (mailbox != "") { clearInterval(updateTimerId) } $("#mailNewButton").click(mailNew) }) function mailNew(e) { window.location.hash = currentFolder + currentPage + "/mailNew" } function mailOpen(id) { window.location.hash = currentFolder + currentPage + "/" + id } function openFolder(folder) { window.location.hash = folder } function onHashChanged() { var hashLocation = window.location.hash if (hashLocation == "") { setDetailsVisible(false) openFolder("Inbox") return } hashRegex = /^#([a-zA-Z]+)(\d*)\/?([A-Fa-f\d]*)/g hashParts = hashRegex.exec(hashLocation) page = 0 if (hashParts.length >= 3 && hashParts[2] != "") { page = parseInt(hashParts[2]) if (typeof page != "number" || page > pageMax || page < 0) { page = 0 } } if (hashParts.length >= 2 && (hashParts[1] != currentFolder || currentPage != page) && hashParts[1] != "") { updateMailList(hashParts[1], page) } if (hashParts.length >= 4 && hashParts[3] != "" && hashParts[3] != "/mailNew") { if (currentMail != hashParts[3]) { requestMail(hashParts[3]) } } else { setDetailsVisible(false) } hashParts = hashLocation.split("/") if (hashParts.length == 2 && hashParts[1] == "mailNew") { console.log("hashParts: " + hashParts + " length" + hashParts.length + " hashParts[1] " + hashParts[1]) setMailNewVisible(true) } else { console.log("!hashParts: " + hashParts) setMailNewVisible(false) } } function requestMail(mailId) { if (mailId != "") { $.ajax({ url: "/mail", data: { mailId: mailId }, success: function(result) { currentMail = mailId $("#mail"+mailId).removeClass("unread") $("#mail"+mailId).addClass("read") $("#mailDetails").html(result); setDetailsVisible(true); folderStat(currentFolder);//TODO: receive statistic from websocket }, error: function(jqXHR, textStatus, errorThrown) { $("#mailDetails").html(textStatus) setDetailsVisible(true) } }) } } function loadFolders() { if (mailbox == "") { $("#folders").html("Unable to load folder list") return } $.ajax({ url: mailbox + "/folders", success: function(result) { folderList = jQuery.parseJSON(result) for(var i = 0; i < folderList.folders.length; i++) { folders.push(folderList.folders[i].name) folderStat(folderList.folders[i].name) } $("#folders").html(folderList.html) }, error: function(jqXHR, textStatus, errorThrown) { //TODO: some toast message here once implemented } }) } function folderStat(folder) { $.ajax({ url: mailbox + "/folderStat", data: { folder: folder }, success: function(result) { var stats = jQuery.parseJSON(result) if (stats.unread > 0) { $("#folderStats"+folder).text(stats.unread) $("#folder"+folder).addClass("unread") } else { $("#folder"+folder).removeClass("unread") $("#folderStats"+folder).text("") } }, error: function(jqXHR, textStatus, errorThrown) { //TODO: some toast message here once implemented } }) } function closeDetails() { window.location.hash = currentFolder + currentPage } function closeMailNew() { window.location.hash = currentFolder + currentPage } function loadStatusLine() { $.ajax({ url: mailbox + "/statusLine", success: function(result) { $("#statusLine").html(result) }, error: function(jqXHR, textStatus, errorThrown) { //TODO: some toast message here once implemented } }) } function localDate(timestamp) { var today = new Date() var date = new Date(timestamp*1000) dateString = "" if (today.getDay() == date.getDay() && today.getMonth() == date.getMonth() && today.getFullYear() == date.getFullYear()) { dateString = date.toLocaleTimeString("en-US") } else if (today.getFullYear() == date.getFullYear()) { const options = { day: 'numeric', month: 'short' } dateString = date.toLocaleDateString("en-US", options) } else { dateString = date.toLocaleDateString("en-US") } return dateString } function setRead(mailId, read) { $.ajax({ url: "/setRead", data: {mailId: mailId, read: read}, success: function(result) { if (read) { if ($("#readIcon"+mailId)) { $("#readIcon"+mailId).attr("src", "/assets/read.svg") } if ($("#readListIcon"+mailId)) { $("#readListIcon"+mailId).attr("src", "/assets/read.svg") } $("#mail"+mailId).removeClass("unread") $("#mail"+mailId).addClass("read") } else { if ($("#readIcon"+mailId)) { $("#readIcon"+mailId).attr("src", "/assets/unread.svg") } if ($("#readListIcon"+mailId)) { $("#readListIcon"+mailId).attr("src", "/assets/unread.svg") } $("#mail"+mailId).removeClass("read") $("#mail"+mailId).addClass("unread") } folderStat(currentFolder);//TODO: receive statistic from websocket }, error: function(jqXHR, textStatus, errorThrown) { } }) } function toggleRead(mailId, iconId) { if ($("#"+iconId+mailId)) { setRead(mailId, $("#"+iconId+mailId).attr("src") == "/assets/unread.svg") } } function removeMail(mailId, callback) { var url = currentFolder != "Trash" ? "/remove" : "/delete" $.ajax({ url: url, data: {mailId: mailId}, success: function(result) { $("#mail"+mailId).remove(); if (callback) { callback(); } folderStat(currentFolder);//TODO: receive statistic from websocket folderStat("Trash");//TODO: receive statistic from websocket }, error: function(jqXHR, textStatus, errorThrown) { } }) } function restoreMail(mailId, callback) { var url = "/restore" $.ajax({ url: url, data: {mailId: mailId}, success: function(result) { if (currentFolder == "Trash") { $("#mail"+mailId).remove(); } if (callback) { callback(); } for (var i = 0; i < folders.length; i++) { folderStat(folders[i]) } }, error: function(jqXHR, textStatus, errorThrown) { } }) } function setDetailsVisible(visible) { if (visible) { $("#mailDetails").show() $("#mailList").css({pointerEvents: "none"}) clearInterval(updateTimerId) } else { currentMail = "" $("#mailDetails").hide() $("#mailDetails").html("") $("#mailList").css({pointerEvents: "auto"}) } } function setMailNewVisible(visible) { if (visible) { $("#mailNew").show() $("#mailList").css({pointerEvents: "none"}) clearInterval(updateTimerId) } else { currentMail = "" $("#mailNew").hide() $("#mailList").css({pointerEvents: "auto"}) } } function updateMailList(folder, page) { if (mailbox == "" || folder == "") { if ($("#mailList")) { $("#mailList").html("Unable to load message list") } return } $.ajax({ url: mailbox + "/mailList", data: { folder: folder, page: page }, success: function(result) { var data = jQuery.parseJSON(result) pageMax = Math.floor(data.total/50) if ($("#mailList")) { $("#mailList").html(data.html) } currentFolder = folder currentPage = page if($("#currentPageIndex")) { $("#currentPageIndex").text(currentPage + 1) } if($("#totalPageCount")) { $("#totalPageCount").text(pageMax + 1) } }, error: function(jqXHR, textStatus, errorThrown) { if ($("#mailList")) { $("#mailList").html("Unable to load message list") } } }) } function nextPage() { var newPage = currentPage < (pageMax - 1) ? currentPage + 1 : pageMax window.location.hash = currentFolder + newPage } function prevPage() { var newPage = currentPage > 0 ? currentPage - 1 : 0 window.location.hash = currentFolder + newPage } function toggleDropDown(dd) { $("#"+dd).toggle() } function sendNewMail() { var formValue = $("#mailNewForm").serialize() $.ajax({ url: mailbox + "/sendNewMail", data: formValue, success: function(result) { $("#newMailEditor").val("") $("#newMailSubject").val("") $("#newMailTo").val("") closeMailNew() }, error: function(jqXHR, textStatus, errorThrown) { //TODO: some toast message here once implemented } }) } function logout() { window.location.href = "/logout" }