Skip to content

Commit

Permalink
Merge pull request #3260 from nextcloud/feature/rename_mailbox
Browse files Browse the repository at this point in the history
Add rename mailbox option
  • Loading branch information
GretaD authored Sep 1, 2020
2 parents abc9c5e + 5d9acc6 commit 472e1e8
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 3 deletions.
5 changes: 5 additions & 0 deletions appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@
'url' => '/api/accounts/{id}/quota',
'verb' => 'GET'
],
[
'name' => 'mailboxes#patch',
'url' => '/api/mailboxes/{id}',
'verb' => 'PATCH'
],
[
'name' => 'mailboxes#sync',
'url' => '/api/mailboxes/{id}/sync',
Expand Down
13 changes: 13 additions & 0 deletions lib/Contracts/IMailManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,19 @@ public function flagMessage(Account $account, string $mailbox, int $uid, string
*/
public function getQuota(Account $account): ?Quota;

/**
* Rename a mailbox and get the new (cached) version
*
* @param Account $account
* @param Mailbox $mailbox
* @param string $name
*
* @return Mailbox
*
* @throw ServiceException
*/
public function renameMailbox(Account $account, Mailbox $mailbox, string $name): Mailbox;

/**
* @param Account $account
* @param Mailbox $mailbox
Expand Down
30 changes: 28 additions & 2 deletions lib/Controller/MailboxesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ public function __construct(string $appName,
* @TrapError
*
* @param int $accountId
*
* @return JSONResponse
*
* @throws ClientException
Expand All @@ -97,6 +98,31 @@ public function index(int $accountId): JSONResponse {
]);
}

/**
* @NoAdminRequired
* @TrapError
*
* @param int $id
* @param string $name
*
* @return JSONResponse
*/
public function patch(int $id,
?string $name = null): JSONResponse {
$mailbox = $this->mailManager->getMailbox($this->currentUserId, $id);
$account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());

if ($name !== null) {
$mailbox = $this->mailManager->renameMailbox(
$account,
$mailbox,
$name
);
}

return new JSONResponse($mailbox);
}

/**
* @NoAdminRequired
* @TrapError
Expand All @@ -121,7 +147,7 @@ public function sync(int $id, array $ids = [], bool $init = false, string $query
$mailbox,
Horde_Imap_Client::SYNC_NEWMSGSUIDS | Horde_Imap_Client::SYNC_FLAGSUIDS | Horde_Imap_Client::SYNC_VANISHEDUIDS,
array_map(function ($id) {
return (int) $id;
return (int)$id;
}, $ids),
!$init,
$query
Expand Down Expand Up @@ -235,7 +261,7 @@ public function destroy(int $id): JSONResponse {
$mailbox = $this->mailManager->getMailbox($this->currentUserId, $id);
$account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());

$this->mailManager->deleteMailbox($account, $mailbox);
$this->mailManager->deleteMailbox($account, $mailbox);
return new JSONResponse();
}
}
13 changes: 13 additions & 0 deletions lib/IMAP/FolderMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,19 @@ public function getFoldersStatusAsObject(Horde_Imap_Client_Socket $client,
);
}

/**
* @param Horde_Imap_Client_Socket $client
* @param string $oldName
* @param string $newName
*
* @throws Horde_Imap_Client_Exception
*/
public function renameFolder(Horde_Imap_Client_Socket $client,
string $oldName,
string $newName): void {
$client->renameMailbox($oldName, $newName);
}

/**
* @param Folder[] $folders
*
Expand Down
25 changes: 25 additions & 0 deletions lib/Service/MailManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,31 @@ public function getQuota(Account $account): ?Quota {
);
}

public function renameMailbox(Account $account, Mailbox $mailbox, string $name): Mailbox {
/*
* 1. Rename on IMAP
*/
$this->folderMapper->renameFolder(
$this->imapClientFactory->getClient($account),
$mailbox->getName(),
$name
);

/**
* 2. Get the IMAP changes into our database cache
*/
$this->mailboxSync->sync($account, true);

/**
* 3. Return the cached object with the new ID
*/
try {
return $this->mailboxMapper->find($account, $name);
} catch (DoesNotExistException $e) {
throw new ServiceException("The renamed mailbox $name does not exist", 0, $e);
}
}

/**
* @param Account $account
* @param Mailbox $mailbox
Expand Down
44 changes: 43 additions & 1 deletion src/components/NavigationMailbox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,24 @@
@click="markAsRead">
{{ t('mail', 'Mark all messages of this mailbox as read') }}
</ActionButton>

<ActionButton
v-if="!editing && top && !account.isUnified && mailbox.specialRole !== 'flagged'"
icon="icon-folder"
@click="openCreateMailbox">
{{ t('mail', 'Add subfolder') }}
</ActionButton>
<ActionInput v-if="editing" icon="icon-folder" @submit.prevent.stop="createMailbox" />
<ActionButton
v-if="renameLabel && !hasSubMailboxes && !account.isUnified"
icon="icon-rename"
@click.prevent.stop="openRenameInput">
{{ t('mail', 'Edit name') }}
</ActionButton>
<ActionInput
v-if="renameInput"
icon="icon-rename"
:value.sync="mailboxName"
@submit.prevent.stop="renameMailbox" />
<ActionText v-if="showSaving" icon="icon-loading-small">
{{ t('mail', 'Saving') }}
</ActionText>
Expand Down Expand Up @@ -101,6 +111,7 @@ import { getMailboxStatus } from '../service/MailboxService'
import logger from '../logger'
import { translatePlural as n } from '@nextcloud/l10n'
import { translate as translateMailboxName } from '../i18n/MailboxTranslator'
import { showInfo } from '@nextcloud/dialogs'
export default {
name: 'NavigationMailbox',
Expand Down Expand Up @@ -140,6 +151,10 @@ export default {
editing: false,
showSubMailboxes: false,
menuOpen: false,
renameLabel: true,
renameInput: false,
mailboxName: this.mailbox.displayName,
}
},
computed: {
Expand Down Expand Up @@ -320,6 +335,33 @@ export default {
}
)
},
async renameMailbox() {
this.renameInput = false
this.showSaving = false
try {
await this.$store.dispatch('renameMailbox', {
account: this.account,
mailbox: this.mailbox,
newName: this.mailboxName,
})
this.renameLabel = true
this.renameInput = false
this.showSaving = false
} catch (error) {
showInfo(t('mail', 'An error occurred, unable to rename the mailbox.'))
console.error(error)
this.renameLabel = false
this.renameInput = false
this.showSaving = true
}
},
openRenameInput() {
// Hide label and show input
this.renameLabel = false
this.renameInput = true
this.showSaving = false
},
},
}
</script>
8 changes: 8 additions & 0 deletions src/service/MailboxService.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,11 @@ export const deleteMailbox = async(id) => {

await axios.delete(url)
}
export async function patchMailbox(id, data) {
const url = generateUrl('/apps/mail/api/mailboxes/{id}', {
id,
})

const response = await axios.patch(url, data)
return response.data
}
10 changes: 10 additions & 0 deletions src/store/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import {
deleteMailbox,
fetchAll as fetchAllMailboxes,
markMailboxRead,
patchMailbox,
} from '../service/MailboxService'
import {
deleteMessage,
Expand Down Expand Up @@ -674,4 +675,13 @@ export default {
await deleteAlias(account, aliasToDelete)
commit('deleteAlias', { account, alias: aliasToDelete })
},
async renameMailbox({ commit }, { account, mailbox, newName }) {
const newMailbox = await patchMailbox(mailbox.databaseId, {
name: newName,
})

console.debug(`mailbox ${mailbox.databaseId} renamed to ${newName}`, { mailbox })
commit('removeMailbox', { id: mailbox.databaseId })
commit('addMailbox', { account, mailbox: newMailbox })
},
}
1 change: 1 addition & 0 deletions src/store/mutations.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,4 +222,5 @@ export default {
deleteAlias(state, { account, alias }) {
account.aliases.splice(account.aliases.indexOf(alias), 1)
},

}

0 comments on commit 472e1e8

Please sign in to comment.