mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-09-07 21:24:24 +08:00
Summary: Now that we don't run Send tasks outside the sync loop, we don't need that awful hack wich required passing a `runTask` callback to `runSyncbackTask` in order to customize how to run the task. Instead, runSyncbackTask now knows 2 ways to run a task, either via imap, or via smtp, depending on the resource declared by task to run. So now SyncbackTasks declare a resource type they need to run, and that will be passed as their second argument when running. Depends D3894 Test Plan: manual Reviewers: mark, halla, spang, evan Reviewed By: halla, spang, evan Differential Revision: https://phab.nylas.com/D3896
65 lines
2 KiB
JavaScript
65 lines
2 KiB
JavaScript
const {Errors: {APIError}} = require('isomorphic-core')
|
|
const {SyncbackIMAPTask} = require('./syncback-task')
|
|
|
|
class RenameLabelIMAP extends SyncbackIMAPTask {
|
|
description() {
|
|
return `RenameLabel`;
|
|
}
|
|
|
|
affectsImapMessageUIDs() {
|
|
return false
|
|
}
|
|
|
|
async run(db, imap) {
|
|
const {sequelize, accountId, Label} = db
|
|
const {labelId, newLabelName} = this.syncbackRequestObject().props
|
|
const oldLabel = await Label.findById(labelId)
|
|
await imap.renameBox(oldLabel.name, newLabelName);
|
|
|
|
// After IMAP succeeds, update the db
|
|
const newId = Label.hash({boxName: newLabelName, accountId})
|
|
let newLabel;
|
|
await sequelize.transaction(async (transaction) => {
|
|
newLabel = await Label.create({
|
|
id: newId,
|
|
accountId,
|
|
name: newLabelName,
|
|
}, {transaction})
|
|
|
|
// We can't do batch updates because we need to generate deltas for each
|
|
// message and thread
|
|
const messages = await oldLabel.getMessages({
|
|
transaction,
|
|
attributes: ['id'],
|
|
include: [{model: Label, as: 'labels', attributes: ['id']}],
|
|
})
|
|
await Promise.all(messages.map(async (m) => {
|
|
const nextLabels = [
|
|
newLabel,
|
|
...m.labels.filter(l => l.id !== oldLabel.id),
|
|
]
|
|
await m.setLabels(nextLabels, {transaction})
|
|
await m.save({transaction})
|
|
}))
|
|
const threads = await oldLabel.getThreads({
|
|
transaction,
|
|
attributes: ['id'],
|
|
include: [{model: Label, as: 'labels', attributes: ['id']}],
|
|
})
|
|
await Promise.all(threads.map(async (t) => {
|
|
const nextLabels = [
|
|
newLabel,
|
|
...t.labels.filter(l => l.id !== oldLabel.id),
|
|
]
|
|
await t.setLabels(nextLabels, {transaction})
|
|
await t.save({transaction})
|
|
}))
|
|
await oldLabel.destroy({transaction})
|
|
})
|
|
if (!newLabel) {
|
|
throw new APIError(`Error renaming label - can't save to database`)
|
|
}
|
|
return newLabel.toJSON()
|
|
}
|
|
}
|
|
module.exports = RenameLabelIMAP
|