@bobfrankston/rmfmail 1.1.248 → 1.1.249
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/app.bundle.js +129 -1
- package/client/app.bundle.js.map +3 -3
- package/client/app.js +155 -0
- package/client/app.js.map +1 -1
- package/client/app.ts +139 -0
- package/client/components/context-menu.js +3 -1
- package/client/components/context-menu.js.map +1 -1
- package/client/components/context-menu.ts +5 -1
- package/client/compose/compose.bundle.js +7 -1
- package/client/compose/compose.bundle.js.map +2 -2
- package/client/lib/api-client.js +6 -0
- package/client/lib/api-client.js.map +1 -1
- package/client/lib/api-client.ts +7 -0
- package/package.json +1 -1
- package/packages/mailx-imap/index.d.ts.map +1 -1
- package/packages/mailx-imap/index.js +24 -0
- package/packages/mailx-imap/index.js.map +1 -1
- package/packages/mailx-imap/index.ts +25 -0
- package/packages/mailx-imap/package-lock.json +2 -2
- package/packages/mailx-imap/package.json +1 -1
- package/packages/mailx-service/index.d.ts +7 -0
- package/packages/mailx-service/index.d.ts.map +1 -1
- package/packages/mailx-service/index.js +15 -0
- package/packages/mailx-service/index.js.map +1 -1
- package/packages/mailx-service/index.ts +15 -0
- package/packages/mailx-service/jsonrpc.js +3 -0
- package/packages/mailx-service/jsonrpc.js.map +1 -1
- package/packages/mailx-service/jsonrpc.ts +3 -0
- package/packages/mailx-service/sync-queue.d.ts +5 -0
- package/packages/mailx-service/sync-queue.d.ts.map +1 -1
- package/packages/mailx-service/sync-queue.js +8 -0
- package/packages/mailx-service/sync-queue.js.map +1 -1
- package/packages/mailx-service/sync-queue.ts +9 -0
package/client/app.bundle.js
CHANGED
|
@@ -26,6 +26,7 @@ __export(api_client_exports, {
|
|
|
26
26
|
connectEvents: () => connectEvents,
|
|
27
27
|
connectWebSocket: () => connectWebSocket,
|
|
28
28
|
consumePendingMailto: () => consumePendingMailto,
|
|
29
|
+
copyMessages: () => copyMessages,
|
|
29
30
|
createCalendarEvent: () => createCalendarEvent,
|
|
30
31
|
createFolder: () => createFolder,
|
|
31
32
|
createTask: () => createTask,
|
|
@@ -345,6 +346,9 @@ function moveMessages(accountId, uids, targetFolderId, targetAccountId) {
|
|
|
345
346
|
function markAsSpamMessages(accountId, uids) {
|
|
346
347
|
return ipc().markAsSpamMessages?.(accountId, uids);
|
|
347
348
|
}
|
|
349
|
+
function copyMessages(accountId, uids, folderIds, targetFolderId) {
|
|
350
|
+
return ipc().copyMessages?.(accountId, uids, folderIds, targetFolderId);
|
|
351
|
+
}
|
|
348
352
|
function undeleteMessage(accountId, uid, folderId) {
|
|
349
353
|
return ipc().undeleteMessage?.(accountId, uid, folderId);
|
|
350
354
|
}
|
|
@@ -652,7 +656,9 @@ function showContextMenu(x, y, items) {
|
|
|
652
656
|
continue;
|
|
653
657
|
}
|
|
654
658
|
const el = document.createElement("div");
|
|
655
|
-
el.className = "ctx-item" + (item.disabled ? " ctx-disabled" : "");
|
|
659
|
+
el.className = "ctx-item" + (item.disabled ? " ctx-disabled" : "") + (item.emphasized ? " ctx-emphasized" : "");
|
|
660
|
+
if (item.emphasized)
|
|
661
|
+
el.style.fontWeight = "600";
|
|
656
662
|
el.textContent = item.label;
|
|
657
663
|
if (item.tooltip)
|
|
658
664
|
el.title = item.tooltip;
|
|
@@ -8106,6 +8112,128 @@ async function performUndo() {
|
|
|
8106
8112
|
document.addEventListener("mailx-moved", (e) => {
|
|
8107
8113
|
pushUndo({ kind: "move", at: Date.now(), payload: e.detail });
|
|
8108
8114
|
});
|
|
8115
|
+
(() => {
|
|
8116
|
+
const SLOP = 6;
|
|
8117
|
+
let cand = null;
|
|
8118
|
+
let active = false;
|
|
8119
|
+
let ghost = null;
|
|
8120
|
+
let suppressContext = false;
|
|
8121
|
+
const style = document.createElement("style");
|
|
8122
|
+
style.textContent = "body.rmf-rdrag, body.rmf-rdrag * { cursor: grabbing !important; }.rmf-rdrag-ghost { position: fixed; z-index: 100000; pointer-events: none; background: var(--color-accent, #1a6dd4); color: #fff; padding: 2px 9px; border-radius: 4px; font: 12px system-ui; box-shadow: 0 2px 8px rgba(0,0,0,.3); }.ft-folder.rmf-rdrag-over { outline: 2px solid var(--color-accent, #1a6dd4); outline-offset: -2px; border-radius: 4px; }";
|
|
8123
|
+
document.head.appendChild(style);
|
|
8124
|
+
const folderAt = (x, y) => document.elementFromPoint(x, y)?.closest?.(".ft-folder") || null;
|
|
8125
|
+
const clearOver = () => document.querySelectorAll(".ft-folder.rmf-rdrag-over").forEach((el) => el.classList.remove("rmf-rdrag-over"));
|
|
8126
|
+
const cleanup = () => {
|
|
8127
|
+
active = false;
|
|
8128
|
+
cand = null;
|
|
8129
|
+
document.body.classList.remove("rmf-rdrag");
|
|
8130
|
+
ghost?.remove();
|
|
8131
|
+
ghost = null;
|
|
8132
|
+
clearOver();
|
|
8133
|
+
};
|
|
8134
|
+
document.addEventListener("mousedown", (e) => {
|
|
8135
|
+
if (e.button !== 2) return;
|
|
8136
|
+
const row = e.target?.closest?.(".ml-row");
|
|
8137
|
+
if (!row) return;
|
|
8138
|
+
const pressed = {
|
|
8139
|
+
accountId: row.dataset.accountId || "",
|
|
8140
|
+
uid: Number(row.dataset.uid),
|
|
8141
|
+
folderId: Number(row.dataset.folderId)
|
|
8142
|
+
};
|
|
8143
|
+
if (!pressed.uid) return;
|
|
8144
|
+
let msgs = getSelectedMessages();
|
|
8145
|
+
if (!msgs.some((m) => m.accountId === pressed.accountId && m.uid === pressed.uid)) msgs = [pressed];
|
|
8146
|
+
cand = { msgs, x: e.clientX, y: e.clientY };
|
|
8147
|
+
active = false;
|
|
8148
|
+
}, true);
|
|
8149
|
+
document.addEventListener("mousemove", (e) => {
|
|
8150
|
+
if (!cand) return;
|
|
8151
|
+
if (!active) {
|
|
8152
|
+
if (Math.abs(e.clientX - cand.x) < SLOP && Math.abs(e.clientY - cand.y) < SLOP) return;
|
|
8153
|
+
active = true;
|
|
8154
|
+
document.body.classList.add("rmf-rdrag");
|
|
8155
|
+
ghost = document.createElement("div");
|
|
8156
|
+
ghost.className = "rmf-rdrag-ghost";
|
|
8157
|
+
ghost.textContent = cand.msgs.length === 1 ? "1 message" : `${cand.msgs.length} messages`;
|
|
8158
|
+
document.body.appendChild(ghost);
|
|
8159
|
+
}
|
|
8160
|
+
if (ghost) {
|
|
8161
|
+
ghost.style.left = `${e.clientX + 14}px`;
|
|
8162
|
+
ghost.style.top = `${e.clientY + 8}px`;
|
|
8163
|
+
}
|
|
8164
|
+
clearOver();
|
|
8165
|
+
folderAt(e.clientX, e.clientY)?.classList.add("rmf-rdrag-over");
|
|
8166
|
+
}, true);
|
|
8167
|
+
document.addEventListener("mouseup", (e) => {
|
|
8168
|
+
if (!cand) return;
|
|
8169
|
+
const wasActive = active;
|
|
8170
|
+
const msgs = cand.msgs;
|
|
8171
|
+
const folder = wasActive ? folderAt(e.clientX, e.clientY) : null;
|
|
8172
|
+
const mx = e.clientX, my = e.clientY;
|
|
8173
|
+
cleanup();
|
|
8174
|
+
if (!wasActive) return;
|
|
8175
|
+
suppressContext = true;
|
|
8176
|
+
if (!folder) return;
|
|
8177
|
+
e.preventDefault();
|
|
8178
|
+
e.stopPropagation();
|
|
8179
|
+
const targetAccount = folder.dataset.accountId || "";
|
|
8180
|
+
const targetFolderId = Number(folder.dataset.folderId);
|
|
8181
|
+
const targetName = folder.querySelector(".ft-folder-name")?.textContent?.trim() || "folder";
|
|
8182
|
+
void showRightDragMenu(mx, my, msgs, targetAccount, targetFolderId, targetName);
|
|
8183
|
+
}, true);
|
|
8184
|
+
document.addEventListener("contextmenu", (e) => {
|
|
8185
|
+
if (suppressContext) {
|
|
8186
|
+
e.preventDefault();
|
|
8187
|
+
e.stopPropagation();
|
|
8188
|
+
suppressContext = false;
|
|
8189
|
+
}
|
|
8190
|
+
}, true);
|
|
8191
|
+
async function showRightDragMenu(x, y, msgs, targetAccount, targetFolderId, targetName) {
|
|
8192
|
+
const { showContextMenu: showContextMenu2 } = await Promise.resolve().then(() => (init_context_menu(), context_menu_exports));
|
|
8193
|
+
const n = msgs.length;
|
|
8194
|
+
const label = n === 1 ? "message" : `${n} messages`;
|
|
8195
|
+
showContextMenu2(x, y, [
|
|
8196
|
+
{ label: `Move ${label} here`, emphasized: true, action: () => void runRightDragOp(msgs, targetAccount, targetFolderId, targetName, "move") },
|
|
8197
|
+
{ label: `Copy ${label} here`, action: () => void runRightDragOp(msgs, targetAccount, targetFolderId, targetName, "copy") }
|
|
8198
|
+
]);
|
|
8199
|
+
}
|
|
8200
|
+
async function runRightDragOp(msgs, targetAccount, targetFolderId, targetName, op) {
|
|
8201
|
+
const status = document.getElementById("status-sync");
|
|
8202
|
+
const api = await Promise.resolve().then(() => (init_api_client(), api_client_exports));
|
|
8203
|
+
const byAccount = /* @__PURE__ */ new Map();
|
|
8204
|
+
for (const m of msgs) {
|
|
8205
|
+
const g = byAccount.get(m.accountId) || { uids: [], folderIds: [] };
|
|
8206
|
+
g.uids.push(m.uid);
|
|
8207
|
+
g.folderIds.push(m.folderId);
|
|
8208
|
+
byAccount.set(m.accountId, g);
|
|
8209
|
+
}
|
|
8210
|
+
if (op === "move") {
|
|
8211
|
+
removeMessagesAndReconcile(msgs);
|
|
8212
|
+
document.dispatchEvent(new CustomEvent("mailx-moved", {
|
|
8213
|
+
detail: { messages: msgs.map((m) => ({ accountId: m.accountId, uid: m.uid, sourceFolderId: m.folderId })) }
|
|
8214
|
+
}));
|
|
8215
|
+
for (const [src, g] of byAccount) {
|
|
8216
|
+
const targetAcct = src === targetAccount ? void 0 : targetAccount;
|
|
8217
|
+
api.moveMessages(src, g.uids, targetFolderId, targetAcct)?.catch?.((err) => {
|
|
8218
|
+
if (status) status.textContent = `Move failed: ${err?.message || err}`;
|
|
8219
|
+
});
|
|
8220
|
+
}
|
|
8221
|
+
if (status) status.textContent = `Moved ${msgs.length} to ${targetName} \u2014 Ctrl+Z to undo`;
|
|
8222
|
+
} else {
|
|
8223
|
+
let skippedXacct = false;
|
|
8224
|
+
for (const [src, g] of byAccount) {
|
|
8225
|
+
if (src !== targetAccount) {
|
|
8226
|
+
skippedXacct = true;
|
|
8227
|
+
continue;
|
|
8228
|
+
}
|
|
8229
|
+
api.copyMessages(src, g.uids, g.folderIds, targetFolderId)?.catch?.((err) => {
|
|
8230
|
+
if (status) status.textContent = `Copy failed: ${err?.message || err}`;
|
|
8231
|
+
});
|
|
8232
|
+
}
|
|
8233
|
+
if (status) status.textContent = skippedXacct ? `Copy across accounts isn't supported yet` : `Copying ${msgs.length} to ${targetName}\u2026`;
|
|
8234
|
+
}
|
|
8235
|
+
}
|
|
8236
|
+
})();
|
|
8109
8237
|
document.getElementById("btn-delete")?.addEventListener("click", deleteSelection);
|
|
8110
8238
|
document.getElementById("btn-tb-delete")?.addEventListener("click", deleteSelection);
|
|
8111
8239
|
document.getElementById("btn-tb-spam")?.addEventListener("click", spamSelectedMessages);
|