Skip to content

Commit

Permalink
Split recipients into to and cc
Browse files Browse the repository at this point in the history
Signed-off-by: Richard Steinmetz <richard@steinmetz.cloud>
  • Loading branch information
st3iny committed Feb 22, 2021
1 parent b3286aa commit 5cc3d81
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 29 deletions.
74 changes: 50 additions & 24 deletions src/components/ThreadAvatarHeader.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<template>
<div ref="avatarHeader" class="avatar-header">
<div v-if="label" class="label">
<span>{{ label }}</span>
</div>
<!-- Participants that can fit in the parent div -->
<RecipientBubble v-for="participant in participants.slice(0,participantsToDisplay)"
:key="participant.email"
Expand Down Expand Up @@ -36,6 +39,11 @@ export default {
Popover,
},
props: {
label: {
type: String,
required: false,
default: '',
},
participants: {
type: Array,
required: true,
Expand Down Expand Up @@ -74,36 +82,42 @@ export default {
return
}
// Compute the number of participants to display depending on the width available
const avatarHeader = this.$refs.avatarHeader
const maxWidth = (avatarHeader.clientWidth - 100) // Reserve 100px for the avatar-more span
// Only include dom element nodes and ignore avatar-more span
const children = Array
.from(this.$refs.avatarHeader.childNodes)
.filter((node) => node.nodeType === Node.ELEMENT_NODE)
.filter((node) => !node.classList.contains('avatar-more'))
// Reserve 100px for the avatar-more span
const maxWidth = this.$refs.avatarHeader.clientWidth - 100
let childrenWidth = 0
let fits = 0
let idx = 0
while (childrenWidth < maxWidth && fits < this.participants.length) {
// Skipping the 'avatar-more' span
if (avatarHeader.childNodes[idx].clientWidth === undefined) {
idx += 3
continue
}
childrenWidth += avatarHeader.childNodes[idx].clientWidth
fits++
idx++
// Calculate full width including margins
const getFullWidth = (node) => {
const styles = window.getComputedStyle(node)
const margins = parseFloat(styles.marginLeft) + parseFloat(styles.marginRight)
return node.clientWidth + margins
}
if (childrenWidth > maxWidth) {
// There's not enough space to show all thread participants
if (fits > 1) {
this.participantsToDisplay = fits - 1
} else if (fits === 0) {
this.participantsToDisplay = 1
} else {
this.participantsToDisplay = fits
// Measure label width if present
if (this.label) {
childrenWidth += getFullWidth(children[0])
children.splice(0, 1)
}
for (const child of children) {
const newWidth = childrenWidth + getFullWidth(child)
if (newWidth > maxWidth) {
break
}
} else {
// There's enough space to show all thread participants
this.participantsToDisplay = this.participants.length
fits++
childrenWidth = newWidth
}
this.participantsToDisplay = fits
},
},
}
Expand Down Expand Up @@ -146,4 +160,16 @@ export default {
::v-deep .user-bubble__title {
cursor: pointer;
}
.label {
display: inline-block;
margin-right: 2px;
vertical-align: middle;
span {
height: 20px;
line-height: 20px;
vertical-align: top;
}
}
</style>
15 changes: 10 additions & 5 deletions src/components/ThreadEnvelope.vue
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,15 @@
</div>
<Loading v-if="loading" />
<template v-else-if="message">
<ThreadAvatarHeader class="recipients" :participants="recipients" />
<ThreadAvatarHeader
class="recipients"
:label="`${t('mail', 'To')}:`"
:participants="envelope.to" />
<ThreadAvatarHeader
v-if="envelope.cc.length > 0"
class="recipients"
:label="`${t('mail', 'Cc')}:`"
:participants="envelope.cc" />
<Message
:envelope="envelope"
:message="message"
Expand Down Expand Up @@ -192,9 +200,6 @@ export default {
},
}
},
recipients() {
return this.envelope.to.concat(this.envelope.cc)
},
},
watch: {
expanded(expanded) {
Expand Down Expand Up @@ -352,7 +357,7 @@ export default {
font-weight: bold;
}
.recipients {
margin-left: 48px;
margin-left: 60px;
margin-right: 38px;
}

Expand Down

0 comments on commit 5cc3d81

Please sign in to comment.