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 authored and ChristophWurst committed Aug 31, 2020
1 parent 00ade2c commit df94a5e
Show file tree
Hide file tree
Showing 9 changed files with 540 additions and 474 deletions.
5 changes: 4 additions & 1 deletion src/components/NavigationMailbox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
@click="clearCache">
{{ t('mail', 'Clear locally cached data, in case there are issues with synchronization.') }}
</ActionButton>
<ActionButton v-if="!account.isUnified && !mailbox.specialRole" icon="icon-delete" @click="deleteMailbox">
<ActionButton v-if="!account.isUnified && !mailbox.specialRole && !hasSubMailboxes" icon="icon-delete" @click="deleteMailbox">
{{ t('mail', 'Delete folder') }}
</ActionButton>
</template>
Expand Down Expand Up @@ -176,6 +176,9 @@ export default {
},
}
},
hasSubMailboxes() {
return this.subMailboxes.length > 0
},
subMailboxes() {
return this.$store.getters.getSubMailboxes(this.mailbox.databaseId)
},
Expand Down
62 changes: 0 additions & 62 deletions src/imap/MailboxHierarchy.js

This file was deleted.

34 changes: 0 additions & 34 deletions src/imap/MailboxPrefix.js

This file was deleted.

1 change: 0 additions & 1 deletion src/store/getters.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ export const getters = {
},
getSubMailboxes: (state, getters) => (id) => {
const mailbox = getters.getMailbox(id)

return mailbox.mailboxes.map((id) => state.mailboxes[id])
},
getUnifiedMailbox: (state) => (specialRole) => {
Expand Down
4 changes: 4 additions & 0 deletions src/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,23 +57,27 @@ export default new Vuex.Store({
accountId: 0,
attributes: ['\\subscribed'],
isUnified: true,
path: '',
specialUse: ['inbox'],
specialRole: 'inbox',
unread: 0,
mailboxes: [],
envelopeLists: {},
name: 'UNIFIED INBOX',
},
[PRIORITY_INBOX_ID]: {
id: PRIORITY_INBOX_ID,
databaseId: PRIORITY_INBOX_ID,
accountId: 0,
attributes: ['\\subscribed'],
isPriorityInbox: true,
path: '',
specialUse: ['inbox'],
specialRole: 'inbox',
unread: 0,
mailboxes: [],
envelopeLists: {},
name: 'PRIORITY INBOX',
},
},
envelopes: {},
Expand Down
72 changes: 30 additions & 42 deletions src/store/mutations.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,37 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import { curry } from 'ramda'
import orderBy from 'lodash/fp/orderBy'
import sortedUniqBy from 'lodash/fp/sortedUniqBy'
import Vue from 'vue'

import { buildMailboxHierarchy } from '../imap/MailboxHierarchy'
import { havePrefix } from '../imap/MailboxPrefix'
import { sortMailboxes } from '../imap/MailboxSorter'
import { normalizedEnvelopeListId } from './normalization'
import { UNIFIED_ACCOUNT_ID } from './constants'

const addMailboxToState = (state, account) => (mailbox) => {
const addMailboxToState = curry((state, account, mailbox) => {
mailbox.accountId = account.id
mailbox.mailboxes = []
mailbox.envelopeLists = {}

// Add all mailboxes (including submailboxes to state, but only toplevel to account
if (mailbox.name.includes(mailbox.delimiter)) {
mailbox.displayName = mailbox.name.substr(mailbox.name.lastIndexOf(mailbox.delimiter) + 1)
mailbox.path = mailbox.name.substr(0, mailbox.name.lastIndexOf(mailbox.delimiter))
} else {
mailbox.displayName = mailbox.name
mailbox.path = ''
}

Vue.set(state.mailboxes, mailbox.databaseId, mailbox)
return mailbox.databaseId
}
const parent = Object.values(state.mailboxes).find(mb => mb.name === mailbox.path)
if (mailbox.path === '' || !parent) {
account.mailboxes.push(mailbox.databaseId)
} else {
parent.mailboxes.push(mailbox.databaseId)
}
})

const sortAccounts = (accounts) => {
accounts.sort((a1, a2) => a1.order - a2.order)
Expand All @@ -55,16 +70,9 @@ export default {
)

// Save the mailboxes to the store, but only keep IDs in the account's mailboxes list
const mailboxes = buildMailboxHierarchy(sortMailboxes(account.mailboxes), havePrefix(account.mailboxes))
const mailboxes = sortMailboxes(account.mailboxes || [])
Vue.set(account, 'mailboxes', [])
const addToState = addMailboxToState(state, account)
mailboxes.forEach((mailbox) => {
// Add all mailboxes (including submailboxes to state, but only toplevel to account
const id = addToState(mailbox)
Vue.set(mailbox, 'mailboxes', mailbox.mailboxes.map(addToState))

account.mailboxes.push(id)
})
mailboxes.map(addMailboxToState(state, account))
},
editAccount(state, account) {
Vue.set(state.accounts, account.id, Object.assign({}, state.accounts[account.id], account))
Expand All @@ -87,27 +95,7 @@ export default {
state.accounts[accountId].collapsed = false
},
addMailbox(state, { account, mailbox }) {
// Flatten the existing ones before updating the hierarchy
const existing = account.mailboxes.map((id) => state.mailboxes[id])
existing.forEach((mailbox) => {
if (!mailbox.mailboxes) {
return
}
mailbox.mailboxes.map((id) => existing.push(state.mailboxes[id]))
mailbox.mailboxes = []
})
// Save the mailboxes to the store, but only keep IDs in the account's mailboxes list
existing.push(mailbox)
const mailboxes = buildMailboxHierarchy(sortMailboxes(existing), havePrefix(existing))
Vue.set(account, 'mailboxes', [])
const addToState = addMailboxToState(state, account)
mailboxes.forEach((mailbox) => {
// Add all mailboxes (including submailboxes to state, but only toplevel to account
const id = addToState(mailbox)
Vue.set(mailbox, 'mailboxes', mailbox.mailboxes.map(addToState))

account.mailboxes.push(id)
})
addMailboxToState(state, account, mailbox)
},
removeMailbox(state, { id }) {
const mailbox = state.mailboxes[id]
Expand All @@ -119,13 +107,13 @@ export default {
throw new Error(`Account ${mailbox.accountId} of mailbox ${id} is unknown`)
}
Vue.delete(state.mailboxes, id)
account.mailboxes = account.mailboxes.filter((mbId) => mbId !== id)
account.mailboxes.forEach((fId) => {
const mailbox = state.mailboxes[fId]
if (mailbox.mailboxes) {
mailbox.mailboxes = mailbox.mailboxes.filter((mbId) => mbId !== id)
}
})

// Travers through the account and the full mailbox tree to find any dangling pointers
const removeRec = (parent) => {
parent.mailboxes = parent.mailboxes.filter((mbId) => mbId !== id)
parent.mailboxes.map(mbid => removeRec(state.mailboxes[mbid]))
}
removeRec(account)
},
addEnvelope(state, { query, envelope }) {
const mailbox = state.mailboxes[envelope.mailboxId]
Expand Down
Loading

0 comments on commit df94a5e

Please sign in to comment.