Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 64 additions & 3 deletions src/components/Message.vue
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,16 @@
</Modal>
</div>
</div>
<router-link v-for="threadMessage in previousThread"
:key="threadMessage.id"
:to="threadRoute(threadMessage)"
class="icon-mail">
<div class="address">
{{ threadMessage.from[0].label }}
</div>
<!-- TODO: instead of subject it should be shown the first line of the message #2666 -->
{{ threadMessage.subject }}
</router-link>
<div :class="[message.hasHtmlBody ? 'mail-message-body mail-message-body-html' : 'mail-message-body']">
<div v-if="message.itineraries.length > 0" class="message-itinerary">
<Itinerary :entries="message.itineraries" :message-id="message.messageId" />
Expand All @@ -90,6 +100,16 @@
</Popover>
<div id="reply-composer" />
</div>
<router-link v-for="threadMessage in successiveThread"
:key="threadMessage.id"
:to="threadRoute(threadMessage)"
class="icon-mail">
<div class="address">
{{ threadMessage.from[0].label }}
</div>
<!-- TODO: instead of subject it should be shown the first line of the message #2666 -->
{{ threadMessage.subject }}
</router-link>
</template>
</AppContentDetails>
</template>
Expand All @@ -104,7 +124,10 @@ import Modal from '@nextcloud/vue/dist/Components/Modal'
import { generateUrl } from '@nextcloud/router'

import AddressList from './AddressList'
import { buildRecipients as buildReplyRecipients, buildReplySubject } from '../ReplyBuilder'
import {
buildRecipients as buildReplyRecipients,
buildReplySubject,
} from '../ReplyBuilder'
import Error from './Error'
import { getRandomMessageErrorMessage } from '../util/ErrorMessageFactory'
import { html, plain } from '../util/text'
Expand Down Expand Up @@ -150,7 +173,7 @@ export default {
},
computed: {
from() {
return this.message.from[0]?.email
return this.message.from.length === 0 ? '?' : this.message.from[0].label || this.message.from[0].email
},
isEncrypted() {
return isPgpgMessage(this.message.hasHtmlBody ? html(this.message.body) : plain(this.message.body))
Expand All @@ -163,6 +186,16 @@ export default {
hasMultipleRecipients() {
return this.replyRecipient.to.concat(this.replyRecipient.cc).length > 1
},
previousThread() {
// Only show younger messages, not the current one
return this.$store.getters.getMessageThread(this.message.databaseId)
.filter(m => m.dateInt > this.message.dateInt)
},
successiveThread() {
// Only show older messages, not the current one
return this.$store.getters.getMessageThread(this.message.databaseId)
.filter(m => m.dateInt < this.message.dateInt)
},
},
watch: {
$route(to, from) {
Expand Down Expand Up @@ -241,6 +274,15 @@ export default {
}
}
},
threadRoute(threadMessage) {
return {
name: 'message',
params: {
mailboxId: threadMessage.mailboxId,
threadId: threadMessage.databaseId,
},
}
},
replyMessage() {
this.$router.push({
name: 'message',
Expand Down Expand Up @@ -321,7 +363,7 @@ export default {
}
</script>

<style lang="scss">
<style lang="scss" scoped>
#mail-message {
flex-grow: 1;
}
Expand All @@ -331,6 +373,25 @@ export default {
margin-bottom: 10px;
position: relative;
}
a {
display: block;
border-bottom: 1px solid var(--color-primary-light);
padding-left: 30px;
margin-bottom: 15px;
horiz-align: center;
opacity: 0.7;

&:hover {
opacity: 1;
}
}
.address {
font-weight: bold;
}
.icon-mail {
background-image: var(--icon-mail-000);
background-position: 0 center;
}

#mail-message-header {
display: flex;
Expand Down
1 change: 1 addition & 0 deletions src/components/MessageHTMLBody.vue
Original file line number Diff line number Diff line change
Expand Up @@ -101,5 +101,6 @@ export default {

#message-frame {
height: 100%;
width: 100%;
}
</style>
7 changes: 7 additions & 0 deletions src/service/MessageService.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@ export function fetchEnvelopes(mailboxId, query, cursor, limit) {
throw convertAxiosError(error)
})
}
export const fetchThread = async(id) => {
const url = generateUrl('apps/mail/api/messages/{id}/thread', {
id,
})
const resp = await axios.get(url)
return resp.data
}

export async function syncEnvelopes(accountId, id, ids, query, init = false) {
const url = generateUrl('/apps/mail/api/mailboxes/{id}/sync', {
Expand Down
8 changes: 7 additions & 1 deletion src/store/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ import {
fetchMessage,
setEnvelopeFlag,
syncEnvelopes,
fetchThread,
} from '../service/MessageService'
import { createAlias, deleteAlias } from '../service/AliasService'
import logger from '../logger'
Expand Down Expand Up @@ -645,8 +646,13 @@ export default {
commit('addMessage', {
message,
})
}

const thread = await fetchThread(message.databaseId)
commit('addMessageThread', {
message,
thread,
})
}
return message
},
async deleteMessage({ getters, commit }, { id }) {
Expand Down
3 changes: 3 additions & 0 deletions src/store/getters.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,7 @@ export const getters = {
getMessage: (state) => (id) => {
return state.messages[id]
},
getMessageThread: (state) => (id) => {
return state.messages[id]?.thread ?? []
},
}
3 changes: 3 additions & 0 deletions src/store/mutations.js
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,9 @@ export default {
addMessage(state, { message }) {
Vue.set(state.messages, message.databaseId, message)
},
addMessageThread(state, { message, thread }) {
Vue.set(message, 'thread', thread)
},
removeMessage(state, { id }) {
Vue.delete(state.messages, id)
},
Expand Down