Skip to content

Commit

Permalink
Build proper folder hierarchy
Browse files Browse the repository at this point in the history
Signed-off-by: Holger Dehnhardt <holger@dehnhardt.org>
  • Loading branch information
dehnhardt committed Aug 19, 2020
1 parent 908c23d commit 363e29d
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 8 deletions.
64 changes: 64 additions & 0 deletions lib/Folder.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ class Folder {
/** @var string[] */
private $specialUse;

/** @var string */
private $path;

/** @var string */
private $displayName;

/** @var string */
/**
* @param Account $account
* @param Horde_Imap_Client_Mailbox $mailbox
Expand Down Expand Up @@ -102,4 +109,61 @@ public function addSpecialUse($use): void {
public function getSpecialUse() {
return $this->specialUse;
}

/**
* @return Folder[]
*/
public function getFolders() {
return $this->folders;
}

/**
* @return boolean
*/
public function isSearchable() {
return !in_array('\noselect', $this->getAttributes());
}

/**
* @return string
*/
public function getDisplayName() {
return $this->displayName;
}

/**
* @return string
*/
public function getPath() {
return $this->path;
}

/**
* @return array
*/
public function jsonSerialize() {
$folders = [];
foreach ($this->folders as $folder) {
$folders[$folder->getMailbox()] = $folder->jsonSerialize();
}
return [
'id' => base64_encode($this->getMailbox()),
'accountId' => $this->accountId,
'displayName' => $this->getDisplayName(),
'path' => $this->getPath(),
'unseen' => isset($this->status['unseen']) ? $this->status['unseen'] : 0,
'total' => isset($this->status['messages']) ? (int) $this->status['messages'] : 0,
'isEmpty' => isset($this->status['messages']) ? 0 >= (int) $this->status['messages'] : true,
'noSelect' => !$this->isSelectable(),
'attributes' => $this->attributes,
'delimiter' => $this->delimiter,
'folders' => array_values($folders),
'specialUse' => $this->specialUse,
'specialRole' => empty($this->specialUse) ? null : $this->specialUse[0],
];
}

public function isSelectable(): bool {
return !in_array('\noselect', $this->attributes);
}
}
14 changes: 9 additions & 5 deletions src/store/getters.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,16 @@ export const getters = {
return state.folders[normalizedFolderId(accountId, folderId)]
},
getFolders: (state) => (accountId) => {
return state.accounts[accountId].folders.map((folderId) => state.folders[folderId])
return state.accounts[accountId].folders
.map((folderId) => state.folders[folderId])
.filter((folder) => folder.path === '')
},
getSubfolders: (state, getters) => (accountId, folderId) => {
const folder = getters.getFolder(accountId, folderId)

return folder.folders.map((id) => state.folders[id])
getSubfolders: (state) => (accountId, folderId) => {
const folder = state.folders[normalizedFolderId(accountId, folderId)]
const path = folder.path + folder.displayName + '/'
return state.accounts[accountId].folders
.map((folderId) => state.folders[folderId])
.filter((folder) => folder.path === path)
},
getUnifiedFolder: (state) => (specialRole) => {
return head(
Expand Down
2 changes: 2 additions & 0 deletions src/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export default new Vuex.Store({
accountId: 0,
attributes: ['\\subscribed'],
isUnified: true,
path: '',
specialUse: ['inbox'],
specialRole: 'inbox',
unread: 0,
Expand All @@ -69,6 +70,7 @@ export default new Vuex.Store({
accountId: 0,
attributes: ['\\subscribed'],
isPriorityInbox: true,
path: '',
specialUse: ['inbox'],
specialRole: 'inbox',
unread: 0,
Expand Down
9 changes: 6 additions & 3 deletions src/store/mutations.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,17 @@ export default {
)

// Save the folders to the store, but only keep IDs in the account's folder list
const folders = buildMailboxHierarchy(sortMailboxes(account.folders || []), havePrefix(account.folders))
const folders = sortMailboxes(account.folders || [])
Vue.set(account, 'folders', [])
const addToState = addFolderToState(state, account)
folders.forEach((folder) => {
// Add all folders (including subfolders to state, but only toplevel to account
const folderPath = atob(folder.id)
const lastSeparatorIndex
= folderPath.lastIndexOf(folder.delimiter) > 0 ? folderPath.lastIndexOf(folder.delimiter) + 1 : 0
folder.displayName = folderPath.substr(lastSeparatorIndex)
folder.path = folderPath.substr(0, lastSeparatorIndex)
const id = addToState(folder)
Vue.set(folder, 'folders', folder.folders.map(addToState))

account.folders.push(id)
})
},
Expand Down

0 comments on commit 363e29d

Please sign in to comment.