2021-09-04 22:16:18 +02:00
|
|
|
//
|
|
|
|
|
// Get the prefered storage
|
|
|
|
|
//
|
2021-09-05 21:47:25 +02:00
|
|
|
function storage(store) {
|
|
|
|
|
if (SysTrayX.Info.browserInfo.majorVersion < 91 || store === "sync") {
|
2021-09-04 22:16:18 +02:00
|
|
|
console.log("Using sync storage");
|
|
|
|
|
return browser.storage.sync;
|
|
|
|
|
} else {
|
|
|
|
|
console.log("Using local storage");
|
|
|
|
|
return browser.storage.local;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Get window startup state
|
|
|
|
|
//
|
|
|
|
|
async function getStartupState() {
|
|
|
|
|
function resolve(result) {
|
|
|
|
|
const startMinimized = result.startMinimized || "false";
|
|
|
|
|
return startMinimized === "true" ? "minimized" : "normal";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function reject() {
|
|
|
|
|
return "normal";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return await storage().get("startMinimized").then(resolve, reject);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Get window restore position state
|
|
|
|
|
//
|
|
|
|
|
async function getRestorePositionsState() {
|
|
|
|
|
function resolve(result) {
|
|
|
|
|
const restorePositions = result.restorePositions || "false";
|
|
|
|
|
return restorePositions;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function reject() {
|
|
|
|
|
return "false";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return await storage().get("restorePositions").then(resolve, reject);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Get window startup window positions
|
|
|
|
|
//
|
|
|
|
|
async function getStartupWindowPositions() {
|
|
|
|
|
function resolve(result) {
|
|
|
|
|
const windowPositions = result.windowPositions || [];
|
|
|
|
|
return windowPositions;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function reject() {
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return await storage().get("windowPositions").then(resolve, reject);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Get close type
|
|
|
|
|
//
|
|
|
|
|
async function getCloseType() {
|
|
|
|
|
function resolve(result) {
|
|
|
|
|
return result.closeType || "1";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function reject() {
|
|
|
|
|
return undefined;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return await storage().get("closeType").then(resolve, reject);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Get KDE integration, default icon hide
|
|
|
|
|
//
|
|
|
|
|
async function getHideDefaultIcon() {
|
|
|
|
|
function resolve(result) {
|
|
|
|
|
const hideDefaultIcon = result.hideDefaultIcon || "false";
|
|
|
|
|
return hideDefaultIcon === "true";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function reject() {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return await storage().get("hideDefaultIcon").then(resolve, reject);
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-24 22:20:30 +01:00
|
|
|
//
|
2020-05-22 22:54:10 +02:00
|
|
|
// Set default default icon
|
2020-01-24 22:20:30 +01:00
|
|
|
// Use <div> as storage
|
|
|
|
|
//
|
|
|
|
|
async function getDefaultIcon() {
|
2021-09-04 22:16:18 +02:00
|
|
|
function resolve(result) {
|
2021-09-05 13:55:39 +02:00
|
|
|
const defaultIconMime = result.defaultIconMime || "";
|
|
|
|
|
const defaultIcon = result.defaultIcon || "";
|
|
|
|
|
return { defaultIconMime, defaultIcon };
|
2020-05-22 22:54:10 +02:00
|
|
|
}
|
|
|
|
|
|
2021-09-04 22:16:18 +02:00
|
|
|
function reject() {
|
2021-09-05 13:55:39 +02:00
|
|
|
return "";
|
2020-05-22 22:54:10 +02:00
|
|
|
}
|
|
|
|
|
|
2021-09-05 13:55:39 +02:00
|
|
|
const { defaultIconMime, defaultIcon } = await storage()
|
2021-09-04 22:16:18 +02:00
|
|
|
.get(["defaultIconMime", "defaultIcon"])
|
|
|
|
|
.then(resolve, reject);
|
2020-05-22 22:54:10 +02:00
|
|
|
|
2021-09-05 13:55:39 +02:00
|
|
|
if (defaultIconMime === "" || defaultIcon === "") {
|
2020-05-22 22:54:10 +02:00
|
|
|
const toDataURL = (url) =>
|
|
|
|
|
fetch(url)
|
|
|
|
|
.then((response) => response.blob())
|
|
|
|
|
.then(
|
|
|
|
|
(blob) =>
|
|
|
|
|
new Promise((resolve, reject) => {
|
|
|
|
|
const reader = new FileReader();
|
|
|
|
|
reader.onloadend = () => resolve(reader.result);
|
|
|
|
|
reader.onerror = reject;
|
|
|
|
|
reader.readAsDataURL(blob);
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Convert image to storage param
|
2023-07-16 20:23:32 +02:00
|
|
|
var defaultIconPath;
|
|
|
|
|
if (SysTrayX.Info.browserInfo.majorVersion < 115) {
|
|
|
|
|
defaultIconPath = "icons/Thunderbird.png";
|
|
|
|
|
} else {
|
|
|
|
|
defaultIconPath = "icons/Thunderbird115.png";
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-05 13:55:39 +02:00
|
|
|
const { defaultIconMimeUrl, defaultIconBase64Url } = await toDataURL(
|
2023-07-16 20:23:32 +02:00
|
|
|
defaultIconPath
|
2020-05-22 22:54:10 +02:00
|
|
|
).then((dataUrl) => {
|
|
|
|
|
const data = dataUrl.split(":").pop().split(",");
|
|
|
|
|
return {
|
2021-09-05 13:55:39 +02:00
|
|
|
defaultIconMimeUrl: data[0].split(";")[0],
|
|
|
|
|
defaultIconBase64Url: data[1],
|
2020-05-22 22:54:10 +02:00
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Store default icon (base64)
|
2021-09-04 22:16:18 +02:00
|
|
|
await storage().set({
|
2021-09-05 13:55:39 +02:00
|
|
|
defaultIconMime: defaultIconMimeUrl,
|
|
|
|
|
defaultIcon: defaultIconBase64Url,
|
2020-05-22 22:54:10 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Store in HTML
|
|
|
|
|
const defaultIconDiv = document.getElementById("defaultIcon");
|
2021-09-05 13:55:39 +02:00
|
|
|
defaultIconDiv.setAttribute("data-default-icon-mime", defaultIconMimeUrl);
|
|
|
|
|
defaultIconDiv.setAttribute("data-default-icon", defaultIconBase64Url);
|
2020-05-22 22:54:10 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Set default unread icon
|
|
|
|
|
// Use <div> as storage
|
|
|
|
|
//
|
|
|
|
|
async function getIcon() {
|
2021-09-04 22:16:18 +02:00
|
|
|
function resolve(result) {
|
2021-09-05 13:55:39 +02:00
|
|
|
const iconMime = result.iconMime || "";
|
|
|
|
|
const icon = result.icon || "";
|
|
|
|
|
return { iconMime, icon };
|
2020-01-24 22:20:30 +01:00
|
|
|
}
|
|
|
|
|
|
2021-09-04 22:16:18 +02:00
|
|
|
function reject() {
|
2021-09-05 13:55:39 +02:00
|
|
|
return "";
|
2020-01-24 22:20:30 +01:00
|
|
|
}
|
|
|
|
|
|
2021-09-05 13:55:39 +02:00
|
|
|
const { iconMime, icon } = await storage()
|
2021-09-04 22:16:18 +02:00
|
|
|
.get(["iconMime", "icon"])
|
|
|
|
|
.then(resolve, reject);
|
2020-01-24 22:20:30 +01:00
|
|
|
|
2021-09-05 13:55:39 +02:00
|
|
|
if (iconMime === "" || icon === "") {
|
2020-05-09 17:10:54 +02:00
|
|
|
const toDataURL = (url) =>
|
2020-01-24 22:20:30 +01:00
|
|
|
fetch(url)
|
2020-05-09 17:10:54 +02:00
|
|
|
.then((response) => response.blob())
|
2020-01-24 22:20:30 +01:00
|
|
|
.then(
|
2020-05-09 17:10:54 +02:00
|
|
|
(blob) =>
|
2020-01-24 22:20:30 +01:00
|
|
|
new Promise((resolve, reject) => {
|
|
|
|
|
const reader = new FileReader();
|
|
|
|
|
reader.onloadend = () => resolve(reader.result);
|
|
|
|
|
reader.onerror = reject;
|
|
|
|
|
reader.readAsDataURL(blob);
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Convert image to storage param
|
2021-09-05 13:55:39 +02:00
|
|
|
const { iconMimeUrl, iconBase64Url } = await toDataURL(
|
|
|
|
|
"icons/blank-icon.png"
|
|
|
|
|
).then((dataUrl) => {
|
|
|
|
|
const data = dataUrl.split(":").pop().split(",");
|
|
|
|
|
return { iconMimeUrl: data[0].split(";")[0], iconBase64Url: data[1] };
|
|
|
|
|
});
|
2020-01-24 22:20:30 +01:00
|
|
|
|
|
|
|
|
// Store default icon (base64)
|
2021-09-04 22:16:18 +02:00
|
|
|
await storage().set({
|
2021-09-05 13:55:39 +02:00
|
|
|
iconMime: iconMimeUrl,
|
|
|
|
|
icon: iconBase64Url,
|
2020-01-24 22:20:30 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Store in HTML
|
|
|
|
|
const iconDiv = document.getElementById("icon");
|
2021-09-05 13:55:39 +02:00
|
|
|
iconDiv.setAttribute("data-icon-mime", iconMimeUrl);
|
|
|
|
|
iconDiv.setAttribute("data-icon", iconBase64Url);
|
2020-01-24 22:20:30 +01:00
|
|
|
}
|
|
|
|
|
}
|
2020-02-29 20:36:08 +01:00
|
|
|
|
2020-05-09 17:10:54 +02:00
|
|
|
//
|
2020-05-12 21:38:03 +02:00
|
|
|
// Get filters
|
2020-05-09 17:10:54 +02:00
|
|
|
//
|
2020-05-12 21:38:03 +02:00
|
|
|
async function getFilters() {
|
2021-09-04 22:16:18 +02:00
|
|
|
function resolve(result) {
|
2021-09-12 16:51:55 +02:00
|
|
|
let filters = result.filters || undefined;
|
2020-05-13 21:24:29 +02:00
|
|
|
|
2021-09-12 16:51:55 +02:00
|
|
|
if (filters === undefined || filters.length === 0) {
|
|
|
|
|
//
|
|
|
|
|
// No filters defined, create base filters
|
|
|
|
|
//
|
|
|
|
|
console.debug("Stored filters: undefined or empty");
|
2020-05-21 12:12:10 +02:00
|
|
|
|
2021-09-12 16:51:55 +02:00
|
|
|
filters = [];
|
|
|
|
|
for (const account of SysTrayX.Messaging.accounts) {
|
|
|
|
|
const inbox = account.folders.filter(
|
|
|
|
|
(folder) => folder.type == "inbox"
|
|
|
|
|
);
|
2020-05-13 21:24:29 +02:00
|
|
|
|
2021-09-12 16:51:55 +02:00
|
|
|
if (inbox.length > 0) {
|
|
|
|
|
let folder = {};
|
|
|
|
|
if (SysTrayX.Info.browserInfo.majorVersion < 91) {
|
|
|
|
|
// console.debug("Folder pre 91: " + JSON.stringify(inbox[0]));
|
|
|
|
|
|
|
|
|
|
folder = {
|
|
|
|
|
...inbox[0],
|
|
|
|
|
accountName: account.name,
|
|
|
|
|
path: "/" + inbox[0].name,
|
|
|
|
|
version: SysTrayX.Info.version,
|
|
|
|
|
};
|
|
|
|
|
delete folder.subFolders;
|
|
|
|
|
|
|
|
|
|
filters.push({
|
|
|
|
|
unread: true,
|
|
|
|
|
folder: folder,
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
// console.debug("Folder 91+: " + JSON.stringify(inbox[0]));
|
|
|
|
|
|
|
|
|
|
filters.push({
|
|
|
|
|
accountId: inbox[0].accountId,
|
|
|
|
|
version: SysTrayX.Info.version,
|
|
|
|
|
folders: [inbox[0].path],
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-09-04 22:16:18 +02:00
|
|
|
|
2021-09-12 16:51:55 +02:00
|
|
|
console.debug("Force new filters: " + JSON.stringify(filters));
|
2021-08-12 22:33:29 +02:00
|
|
|
} else {
|
2021-09-12 16:51:55 +02:00
|
|
|
console.debug("Stored filters: " + JSON.stringify(filters));
|
2021-08-12 22:33:29 +02:00
|
|
|
}
|
|
|
|
|
|
2021-09-12 16:51:55 +02:00
|
|
|
return filters;
|
2021-08-10 19:58:16 +02:00
|
|
|
}
|
2020-05-09 17:10:54 +02:00
|
|
|
|
2021-09-04 22:16:18 +02:00
|
|
|
function reject() {
|
2020-05-09 17:10:54 +02:00
|
|
|
return undefined;
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-04 22:16:18 +02:00
|
|
|
return await storage().get("filters").then(resolve, reject);
|
2020-05-09 17:10:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Get count type
|
|
|
|
|
//
|
|
|
|
|
async function getCountType() {
|
2021-09-04 22:16:18 +02:00
|
|
|
function resolve(result) {
|
2020-05-09 17:10:54 +02:00
|
|
|
return result.countType || "0";
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-04 22:16:18 +02:00
|
|
|
function reject() {
|
2020-08-02 21:32:09 +02:00
|
|
|
return undefined;
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-04 22:16:18 +02:00
|
|
|
return await storage().get("countType").then(resolve, reject);
|
2020-08-02 21:32:09 +02:00
|
|
|
}
|
2021-08-10 19:58:16 +02:00
|
|
|
|
2023-08-22 16:02:06 +02:00
|
|
|
//
|
2023-08-25 20:44:32 +02:00
|
|
|
// Get start app parameters
|
2023-08-22 16:02:06 +02:00
|
|
|
//
|
2023-08-25 18:18:20 +02:00
|
|
|
async function getStartAppParam() {
|
2023-08-22 16:02:06 +02:00
|
|
|
function resolve(result) {
|
2023-08-25 18:18:20 +02:00
|
|
|
const startApp = result.startApp || "";
|
|
|
|
|
const startAppArgs = result.startAppArgs || "";
|
|
|
|
|
return { startApp, startAppArgs };
|
2023-08-22 16:02:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function reject() {
|
2023-08-25 18:18:20 +02:00
|
|
|
return { startApp: "", startAppArgs: "" };
|
2023-08-22 16:02:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return await storage()
|
2023-08-25 18:18:20 +02:00
|
|
|
.get(["startApp", "startAppArgs"])
|
2023-08-22 16:02:06 +02:00
|
|
|
.then(resolve, reject);
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-10 19:58:16 +02:00
|
|
|
// Helper funcs for TB91 and later folder handling
|
|
|
|
|
|
2021-08-10 21:39:35 +02:00
|
|
|
async function getMailFolderInfo(folder) {
|
|
|
|
|
return await browser.folders.getFolderInfo(folder);
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-10 19:58:16 +02:00
|
|
|
// Check if a folder is in the filter list
|
2021-08-10 20:13:33 +02:00
|
|
|
function isFolderInFilters(folder) {
|
2021-09-12 16:51:55 +02:00
|
|
|
const accountIndex = SysTrayX.Messaging.filters.findIndex(
|
|
|
|
|
(account) => account.accountId === folder.accountId
|
2021-08-10 19:58:16 +02:00
|
|
|
);
|
2021-09-12 16:51:55 +02:00
|
|
|
|
|
|
|
|
if (accountIndex !== -1) {
|
|
|
|
|
return (
|
|
|
|
|
SysTrayX.Messaging.filters[accountIndex].folders.filter(
|
|
|
|
|
(path) => path === folder.path
|
|
|
|
|
).length > 0
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2021-08-10 19:58:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check if the parent folder of a folder is in the filter list
|
2021-08-10 20:13:33 +02:00
|
|
|
function isParentFolderInFilters(folder) {
|
2021-08-10 19:58:16 +02:00
|
|
|
const parentPath = folder.path.substring(0, folder.path.lastIndexOf("/"));
|
|
|
|
|
|
2021-09-12 16:51:55 +02:00
|
|
|
const accountIndex = SysTrayX.Messaging.filters.findIndex(
|
|
|
|
|
(account) => account.accountId === folder.accountId
|
2021-08-10 19:58:16 +02:00
|
|
|
);
|
2021-09-12 16:51:55 +02:00
|
|
|
|
|
|
|
|
if (accountIndex !== -1) {
|
|
|
|
|
return (
|
|
|
|
|
SysTrayX.Messaging.filters[accountIndex].folders.filter(
|
|
|
|
|
(path) => path === parentPath
|
|
|
|
|
).length > 0
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2021-08-10 19:58:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Delete a folder from the filter list
|
2021-09-04 22:16:18 +02:00
|
|
|
async function deleteFolderFromFilters(folder) {
|
2021-09-12 16:51:55 +02:00
|
|
|
const accountIndex = SysTrayX.Messaging.filters.findIndex(
|
|
|
|
|
(account) => account.accountId === folder.accountId
|
2021-08-10 19:58:16 +02:00
|
|
|
);
|
|
|
|
|
|
2021-09-12 16:51:55 +02:00
|
|
|
if (accountIndex !== -1) {
|
|
|
|
|
const account = SysTrayX.Messaging.filters[accountIndex];
|
|
|
|
|
account.folders = account.folders.filter((path) => path !== folder.path);
|
|
|
|
|
|
|
|
|
|
// Store the new filters
|
|
|
|
|
await storage().set({
|
|
|
|
|
filters: SysTrayX.Messaging.filters,
|
|
|
|
|
});
|
|
|
|
|
}
|
2021-08-10 19:58:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get the account name from an id
|
|
|
|
|
function getAccountName(id) {
|
2021-09-12 16:51:55 +02:00
|
|
|
const account = SysTrayX.Messaging.accounts.find(
|
2021-08-10 19:58:16 +02:00
|
|
|
(account) => account.id === id
|
2021-09-12 16:51:55 +02:00
|
|
|
);
|
2021-08-10 19:58:16 +02:00
|
|
|
|
|
|
|
|
return account.name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Add a folder to the filter list
|
2021-09-04 22:16:18 +02:00
|
|
|
async function addFolderToFilters(newFolder) {
|
2021-09-12 16:51:55 +02:00
|
|
|
const accountIndex = SysTrayX.Messaging.filters.findIndex(
|
|
|
|
|
(account) => account.accountId === newFolder.accountId
|
|
|
|
|
);
|
2021-09-05 21:47:25 +02:00
|
|
|
|
2021-09-12 16:51:55 +02:00
|
|
|
if (accountIndex !== -1) {
|
|
|
|
|
const account = SysTrayX.Messaging.filters[accountIndex];
|
|
|
|
|
account.folders.push(newFolder.path);
|
|
|
|
|
|
|
|
|
|
// Store the new filter
|
|
|
|
|
await storage().set({
|
|
|
|
|
filters: SysTrayX.Messaging.filters,
|
|
|
|
|
});
|
|
|
|
|
}
|
2021-09-05 21:47:25 +02:00
|
|
|
}
|
2022-06-20 20:48:48 +02:00
|
|
|
|
2023-08-25 15:48:27 +02:00
|
|
|
// Count the unread and new mails
|
|
|
|
|
const getMailCount = () => {
|
|
|
|
|
let unreadCount = 0;
|
|
|
|
|
let newCount = 0;
|
2022-06-20 20:48:48 +02:00
|
|
|
SysTrayX.Messaging.filters.forEach((filter) => {
|
|
|
|
|
const accountId = filter.accountId;
|
|
|
|
|
filter.folders.forEach((path) => {
|
|
|
|
|
if (SysTrayX.Messaging.unread[accountId] !== undefined) {
|
|
|
|
|
if (SysTrayX.Messaging.unread[accountId][path] !== undefined) {
|
2023-08-25 15:48:27 +02:00
|
|
|
unreadCount = unreadCount + SysTrayX.Messaging.unread[accountId][path];
|
2022-06-20 20:48:48 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (SysTrayX.Messaging.new[accountId] !== undefined) {
|
|
|
|
|
if (SysTrayX.Messaging.new[accountId][path] !== undefined) {
|
2023-08-25 15:48:27 +02:00
|
|
|
newCount = newCount + SysTrayX.Messaging.new[accountId][path].length;
|
2022-06-20 20:48:48 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2022-07-03 17:56:40 +02:00
|
|
|
//console.debug("Filters: " + JSON.stringify(SysTrayX.Messaging.filters));
|
|
|
|
|
//console.debug("New: " + JSON.stringify(SysTrayX.Messaging.new));
|
2022-06-20 20:48:48 +02:00
|
|
|
|
2023-08-25 15:48:27 +02:00
|
|
|
//console.debug("getMailCount: " + unreadCount + ", " + newCount);
|
|
|
|
|
SysTrayX.Link.postSysTrayXMessage( { mailCount: { unread: unreadCount, new: newCount } } );
|
2022-07-03 14:16:05 +02:00
|
|
|
};
|