mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-09-11 23:24:32 +08:00
[local-sync] Refactor tasks and /actually/ fix moving between Gmail folders
Moving to between gmail folders (all, spam, trash) or moving to inbox, involves changing labels /and/ folders, simultaneously. For this I added a task to perform both operations, and apply labels first before attempting to move the folder
This commit is contained in:
parent
4b4ab726e2
commit
d650be5429
8 changed files with 89 additions and 56 deletions
|
@ -76,7 +76,16 @@ module.exports = (server) => {
|
||||||
},
|
},
|
||||||
handler: (request, reply) => {
|
handler: (request, reply) => {
|
||||||
const payload = request.payload
|
const payload = request.payload
|
||||||
if (payload.folder_id || payload.folder) {
|
if ((payload.folder_id || payload.folder) && (payload.label_ids || payload.labels)) {
|
||||||
|
createSyncbackRequest(request, reply, {
|
||||||
|
type: "SetThreadFolderAndLabels",
|
||||||
|
props: {
|
||||||
|
folderId: payload.folder_id || payload.folder,
|
||||||
|
labelIds: payload.label_ids || payload.labels,
|
||||||
|
threadId: request.params.id,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
} else if (payload.folder_id || payload.folder) {
|
||||||
createSyncbackRequest(request, reply, {
|
createSyncbackRequest(request, reply, {
|
||||||
type: "MoveThreadToFolder",
|
type: "MoveThreadToFolder",
|
||||||
props: {
|
props: {
|
||||||
|
|
|
@ -11,6 +11,8 @@ class SyncbackTaskFactory {
|
||||||
Task = require('./syncback_tasks/move-thread-to-folder.imap'); break;
|
Task = require('./syncback_tasks/move-thread-to-folder.imap'); break;
|
||||||
case "SetThreadLabels":
|
case "SetThreadLabels":
|
||||||
Task = require('./syncback_tasks/set-thread-labels.imap'); break;
|
Task = require('./syncback_tasks/set-thread-labels.imap'); break;
|
||||||
|
case "SetThreadFolderAndLabels":
|
||||||
|
Task = require('./syncback_tasks/set-thread-folder-and-labels.imap'); break;
|
||||||
case "MarkThreadAsRead":
|
case "MarkThreadAsRead":
|
||||||
Task = require('./syncback_tasks/mark-thread-as-read.imap'); break;
|
Task = require('./syncback_tasks/mark-thread-as-read.imap'); break;
|
||||||
case "MarkThreadAsUnread":
|
case "MarkThreadAsUnread":
|
||||||
|
|
|
@ -6,16 +6,12 @@ class MoveMessageToFolderIMAP extends SyncbackTask {
|
||||||
return `MoveMessageToFolder`;
|
return `MoveMessageToFolder`;
|
||||||
}
|
}
|
||||||
|
|
||||||
run(db, imap) {
|
async run(db, imap) {
|
||||||
const messageId = this.syncbackRequestObject().props.messageId
|
const messageId = this.syncbackRequestObject().props.messageId
|
||||||
const toFolderId = this.syncbackRequestObject().props.folderId
|
const targetFolderId = this.syncbackRequestObject().props.folderId
|
||||||
|
|
||||||
return TaskHelpers.openMessageBox({messageId, db, imap})
|
const {box, message} = await TaskHelpers.openMessageBox({messageId, db, imap})
|
||||||
.then(({box, message}) => {
|
return TaskHelpers.moveMessageToFolder({db, box, message, targetFolderId})
|
||||||
return db.Folder.findById(toFolderId).then((newFolder) => {
|
|
||||||
return box.moveFromBox(message.folderImapUID, newFolder.name)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
module.exports = MoveMessageToFolderIMAP
|
module.exports = MoveMessageToFolderIMAP
|
||||||
|
|
|
@ -6,17 +6,18 @@ class MoveThreadToFolderIMAP extends SyncbackTask {
|
||||||
return `MoveThreadToFolder`;
|
return `MoveThreadToFolder`;
|
||||||
}
|
}
|
||||||
|
|
||||||
run(db, imap) {
|
async run(db, imap) {
|
||||||
const threadId = this.syncbackRequestObject().props.threadId
|
const threadId = this.syncbackRequestObject().props.threadId
|
||||||
const toFolderId = this.syncbackRequestObject().props.folderId
|
const targetFolderId = this.syncbackRequestObject().props.folderId
|
||||||
|
|
||||||
const eachMsg = ({message, box}) => {
|
return TaskHelpers.forEachMessageInThread({
|
||||||
return db.Folder.findById(toFolderId).then((category) => {
|
db,
|
||||||
return box.moveFromBox(message.folderImapUID, category.name)
|
imap,
|
||||||
|
threadId,
|
||||||
|
async callback({message, box}) {
|
||||||
|
return TaskHelpers.moveMessageToFolder({db, box, message, targetFolderId})
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return TaskHelpers.forEachMessageInThread({threadId, db, imap, callback: eachMsg})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
module.exports = MoveThreadToFolderIMAP
|
module.exports = MoveThreadToFolderIMAP
|
||||||
|
|
|
@ -6,28 +6,12 @@ class SetMessageLabelsIMAP extends SyncbackTask {
|
||||||
return `SetMessageLabels`;
|
return `SetMessageLabels`;
|
||||||
}
|
}
|
||||||
|
|
||||||
run(db, imap) {
|
async run(db, imap) {
|
||||||
const messageId = this.syncbackRequestObject().props.messageId
|
const messageId = this.syncbackRequestObject().props.messageId
|
||||||
const labelIds = this.syncbackRequestObject().props.labelIds
|
const labelIds = this.syncbackRequestObject().props.labelIds
|
||||||
|
|
||||||
return TaskHelpers.openMessageBox({messageId, db, imap})
|
const {box, message} = await TaskHelpers.openMessageBox({messageId, db, imap})
|
||||||
.then(({box, message}) => {
|
return TaskHelpers.setMessageLabels({message, db, box, labelIds})
|
||||||
if (!labelIds || labelIds.length === 0) {
|
|
||||||
return message.getLabels().then((labels) => {
|
|
||||||
const labelNames = labels.map(({name}) => name)
|
|
||||||
return box.removeLabels(message.folderImapUID, labelNames)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return db.Label.findAll({
|
|
||||||
where: {
|
|
||||||
id: {'in': labelIds},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((labels) => {
|
|
||||||
const labelNames = labels.map(({name}) => name)
|
|
||||||
return box.setLabels(message.folderImapUID, labelNames)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
module.exports = SetMessageLabelsIMAP
|
module.exports = SetMessageLabelsIMAP
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
const SyncbackTask = require('./syncback-task')
|
||||||
|
const TaskHelpers = require('./task-helpers')
|
||||||
|
|
||||||
|
class SetThreadFolderAndLabelsIMAP extends SyncbackTask {
|
||||||
|
description() {
|
||||||
|
return `SetThreadFolderAndLabels`;
|
||||||
|
}
|
||||||
|
|
||||||
|
async run(db, imap) {
|
||||||
|
const threadId = this.syncbackRequestObject().props.threadId
|
||||||
|
const labelIds = this.syncbackRequestObject().props.labelIds
|
||||||
|
const targetFolderId = this.syncbackRequestObject().props.folderId
|
||||||
|
|
||||||
|
// Ben TODO this is super inefficient because it makes IMAP requests
|
||||||
|
// one UID at a time, rather than gathering all the UIDs and making
|
||||||
|
// a single removeLabels call.
|
||||||
|
return TaskHelpers.forEachMessageInThread({
|
||||||
|
db,
|
||||||
|
imap,
|
||||||
|
threadId,
|
||||||
|
async callback({message, box}) {
|
||||||
|
await TaskHelpers.setMessageLabels({message, db, box, labelIds})
|
||||||
|
return TaskHelpers.moveMessageToFolder({db, box, message, targetFolderId})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
module.exports = SetThreadFolderAndLabelsIMAP
|
||||||
|
|
|
@ -10,23 +10,6 @@ class SetThreadLabelsIMAP extends SyncbackTask {
|
||||||
const threadId = this.syncbackRequestObject().props.threadId
|
const threadId = this.syncbackRequestObject().props.threadId
|
||||||
const labelIds = this.syncbackRequestObject().props.labelIds
|
const labelIds = this.syncbackRequestObject().props.labelIds
|
||||||
|
|
||||||
if (!labelIds || labelIds.length === 0) {
|
|
||||||
return TaskHelpers.forEachMessageInThread({
|
|
||||||
db,
|
|
||||||
imap,
|
|
||||||
threadId,
|
|
||||||
callback: ({message, box}) => {
|
|
||||||
return message.getLabels().then((labels) => {
|
|
||||||
const labelIdentifiers = labels.map(label => label.imapLabelIdentifier())
|
|
||||||
return box.removeLabels(message.folderImapUID, labelIdentifiers)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const labels = await db.Label.findAll({where: {id: labelIds}});
|
|
||||||
const labelIdentifiers = labels.map(label => label.imapLabelIdentifier());
|
|
||||||
|
|
||||||
// Ben TODO this is super inefficient because it makes IMAP requests
|
// Ben TODO this is super inefficient because it makes IMAP requests
|
||||||
// one UID at a time, rather than gathering all the UIDs and making
|
// one UID at a time, rather than gathering all the UIDs and making
|
||||||
// a single removeLabels call.
|
// a single removeLabels call.
|
||||||
|
@ -34,8 +17,8 @@ class SetThreadLabelsIMAP extends SyncbackTask {
|
||||||
db,
|
db,
|
||||||
imap,
|
imap,
|
||||||
threadId,
|
threadId,
|
||||||
callback: ({message, box}) => {
|
async callback({message, box}) {
|
||||||
return box.setLabels(message.folderImapUID, labelIdentifiers)
|
return TaskHelpers.setMessageLabels({message, db, box, labelIds})
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,5 +33,34 @@ const TaskHelpers = {
|
||||||
})
|
})
|
||||||
}))
|
}))
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async moveMessageToFolder({db, box, message, targetFolderId}) {
|
||||||
|
if (!targetFolderId) {
|
||||||
|
throw new Error('TaskHelpers.moveMessageToFolder: targetFolderId is required')
|
||||||
|
}
|
||||||
|
if (targetFolderId === message.folderId) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
const targetFolder = await db.Folder.findById(targetFolderId)
|
||||||
|
if (!targetFolder) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
return box.moveFromBox(message.folderImapUID, targetFolder.name)
|
||||||
|
},
|
||||||
|
|
||||||
|
async setMessageLabels({db, box, message, labelIds}) {
|
||||||
|
if (!labelIds || labelIds.length === 0) {
|
||||||
|
const labels = await message.getLabels()
|
||||||
|
if (labels.length === 0) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
const labelIdentifiers = labels.map(label => label.imapLabelIdentifier())
|
||||||
|
return box.removeLabels(message.folderImapUID, labelIdentifiers)
|
||||||
|
}
|
||||||
|
|
||||||
|
const labels = await db.Label.findAll({where: {id: labelIds}});
|
||||||
|
const labelIdentifiers = labels.map(label => label.imapLabelIdentifier());
|
||||||
|
return box.setLabels(message.folderImapUID, labelIdentifiers)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
module.exports = TaskHelpers
|
module.exports = TaskHelpers
|
||||||
|
|
Loading…
Add table
Reference in a new issue