/** * JSON-RPC dispatcher for WebMailxService. * Maps mailxapi action names to WebMailxService method calls. * Same dispatch table as desktop jsonrpc.ts but adapted for async settings. */ type ServiceLike = Record any>; export interface RpcRequest { _action: string; _cbid: string; [key: string]: any; } export interface RpcResponse { _cbid: string; result?: any; error?: string; } /** Dispatch an incoming mailxapi call to the appropriate WebMailxService method */ export async function dispatch(svc: ServiceLike, req: RpcRequest): Promise { const { _action, _cbid, ...params } = req; try { const result = await dispatchAction(svc, _action, params); return { _cbid, result }; } catch (e: any) { return { _cbid, error: e.message || String(e) }; } } async function dispatchAction(svc: ServiceLike, action: string, p: Record): Promise { switch (action) { case "getAccounts": return svc.getAccounts(); case "getFolders": return svc.getFolders(p.accountId); case "getMessages": return svc.getMessages(p.accountId, p.folderId, p.page, p.pageSize); case "getUnifiedInbox": return svc.getUnifiedInbox(p.page || 1, p.pageSize || 50); case "getMessage": return svc.getMessage(p.accountId, p.uid, p.allowRemote, p.folderId); case "updateFlags": await svc.updateFlags(p.accountId, p.uid, p.flags); return { ok: true }; case "deleteMessage": await svc.deleteMessage(p.accountId, p.uid); return { ok: true }; case "deleteMessages": await svc.deleteMessages(p.accountId, p.uids); return { ok: true, count: p.uids.length }; case "undeleteMessage": await svc.undeleteMessage(p.accountId, p.uid, p.folderId); return { ok: true }; case "moveMessage": await svc.moveMessage(p.accountId, p.uid, p.targetFolderId, p.targetAccountId); return { ok: true }; case "moveMessages": await svc.moveMessages(p.accountId, p.uids, p.targetFolderId); return { ok: true, count: p.uids.length }; case "markFolderRead": svc.markFolderRead(p.folderId); return { ok: true }; case "sendMessage": await svc.send(p); return { ok: true }; case "saveDraft": return svc.saveDraft(p.accountId, p.subject, p.bodyHtml, p.bodyText, p.to, p.cc, p.previousDraftUid, p.draftId); case "deleteDraft": await svc.deleteDraft(p.accountId, p.draftUid); return { ok: true }; case "syncAll": await svc.syncAll(); return { ok: true }; case "syncAccount": await svc.syncAccount(p.accountId); return { ok: true }; case "getSyncPending": return svc.getSyncPending(); case "reauthenticate": return { ok: await svc.reauthenticate(p.accountId) }; case "searchMessages": return svc.search(p.query, p.page, p.pageSize, p.scope, p.accountId, p.folderId); case "searchContacts": return svc.searchContacts(p.query); case "listContacts": return svc.listContacts(p.query || "", p.page || 1, p.pageSize || 100); case "upsertContact": return svc.upsertContact(p.name || "", p.email); case "deleteContact": return svc.deleteContact(p.email); case "addContact": return svc.addContact(p.name || "", p.email); case "getSettings": return svc.getSettings(); case "saveSettingsData": await svc.saveSettingsData(p); return { ok: true }; case "allowRemoteContent": await svc.allowRemoteContent(p.type, p.value); return { ok: true }; case "flagSenderOrDomain": return await svc.flagSenderOrDomain(p.type, p.value); case "getPriorityLists": return await svc.getPriorityLists(); case "setPrioritySender": await svc.setPrioritySender(p.email, !!p.value, p.name); return { ok: true }; case "setPriorityDomain": await svc.setPriorityDomain(p.domain, !!p.value); return { ok: true }; case "getVersion": return { version: "1.0.0-android", theme: "system", storage: svc.getStorageInfo(), platform: "android" }; case "getAutocompleteSettings": return svc.getAutocompleteSettings(); case "saveAutocompleteSettings": await svc.saveAutocompleteSettings(p); return { ok: true }; case "resetStore": await svc.resetStore(); return { ok: true }; default: throw new Error(`Unknown action: ${action}`); } }