mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-01-06 08:08:10 +08:00
165 lines
4.4 KiB
JavaScript
165 lines
4.4 KiB
JavaScript
const { React, PropTypes, Utils } = require('mailspring-exports');
|
|
|
|
class ThreadListParticipants extends React.Component {
|
|
static displayName = 'ThreadListParticipants';
|
|
|
|
static propTypes = { thread: PropTypes.object.isRequired };
|
|
|
|
shouldComponentUpdate(nextProps) {
|
|
if (nextProps.thread === this.props.thread) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
render() {
|
|
const items = this.getTokens();
|
|
return <div className="participants">{this.renderSpans(items)}</div>;
|
|
}
|
|
|
|
renderSpans(items) {
|
|
const spans = [];
|
|
let accumulated = null;
|
|
let accumulatedUnread = false;
|
|
|
|
const flush = function() {
|
|
if (accumulated) {
|
|
spans.push(
|
|
<span key={spans.length} className={`unread-${accumulatedUnread}`}>
|
|
{accumulated}
|
|
</span>
|
|
);
|
|
}
|
|
accumulated = null;
|
|
accumulatedUnread = false;
|
|
};
|
|
|
|
const accumulate = function(text, unread) {
|
|
if (accumulated && unread && accumulatedUnread !== unread) {
|
|
flush();
|
|
}
|
|
if (accumulated) {
|
|
accumulated += text;
|
|
} else {
|
|
accumulated = text;
|
|
accumulatedUnread = unread;
|
|
}
|
|
};
|
|
|
|
for (let idx = 0; idx < items.length; idx++) {
|
|
const { spacer, contact, unread } = items[idx];
|
|
if (spacer) {
|
|
accumulate('...');
|
|
} else {
|
|
var short;
|
|
if (contact.name && contact.name.length > 0) {
|
|
if (items.length > 1) {
|
|
short = contact.displayName({ includeAccountLabel: false, compact: true });
|
|
} else {
|
|
short = contact.displayName({ includeAccountLabel: false });
|
|
}
|
|
} else {
|
|
short = contact.email;
|
|
}
|
|
if (idx < items.length - 1 && !items[idx + 1].spacer) {
|
|
short += ', ';
|
|
}
|
|
accumulate(short, unread);
|
|
}
|
|
}
|
|
|
|
if (!this.props.thread.__messages) {
|
|
throw new Error('ThreadListParticipants requires __messages.');
|
|
}
|
|
|
|
const messages = this.props.thread.__messages != null ? this.props.thread.__messages : [];
|
|
if (messages.length > 1) {
|
|
accumulate(` (${messages.length})`);
|
|
}
|
|
|
|
flush();
|
|
|
|
return spans;
|
|
}
|
|
|
|
getTokensFromMessages = () => {
|
|
const messages = this.props.thread.__messages;
|
|
const tokens = [];
|
|
|
|
let field = 'from';
|
|
if (messages.every(message => message.isFromMe())) {
|
|
field = 'to';
|
|
}
|
|
|
|
for (let idx = 0; idx < messages.length; idx++) {
|
|
const message = messages[idx];
|
|
if (message.draft) {
|
|
continue;
|
|
}
|
|
|
|
for (let contact of message[field]) {
|
|
if (tokens.length === 0) {
|
|
tokens.push({ contact, unread: message.unread });
|
|
} else {
|
|
const lastToken = tokens[tokens.length - 1];
|
|
const lastContact = lastToken.contact;
|
|
|
|
const sameEmail = Utils.emailIsEquivalent(lastContact.email, contact.email);
|
|
const sameName = lastContact.name === contact.name;
|
|
if (sameEmail && sameName) {
|
|
if (!lastToken.unread) {
|
|
lastToken.unread = message.unread;
|
|
}
|
|
} else {
|
|
tokens.push({ contact, unread: message.unread });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return tokens;
|
|
};
|
|
|
|
getTokensFromParticipants = () => {
|
|
let contacts = this.props.thread.participants != null ? this.props.thread.participants : [];
|
|
contacts = contacts.filter(contact => !contact.isMe());
|
|
return contacts.map(contact => ({ contact, unread: false }));
|
|
};
|
|
|
|
getTokens = () => {
|
|
let list;
|
|
if (this.props.thread.__messages instanceof Array) {
|
|
list = this.getTokensFromMessages();
|
|
} else {
|
|
list = this.getTokensFromParticipants();
|
|
}
|
|
|
|
// If no participants, we should at least add current user as sole participant
|
|
if (
|
|
list.length === 0 &&
|
|
(this.props.thread.participants != null ? this.props.thread.participants.length : undefined) >
|
|
0
|
|
) {
|
|
list.push({ contact: this.props.thread.participants[0], unread: false });
|
|
}
|
|
|
|
// We only ever want to show three. Ben...Kevin... Marty
|
|
// But we want the *right* three.
|
|
if (list.length > 3) {
|
|
const listTrimmed = [
|
|
// Always include the first item
|
|
list[0],
|
|
{ spacer: true },
|
|
|
|
// Always include last two items
|
|
list[list.length - 2],
|
|
list[list.length - 1],
|
|
];
|
|
list = listTrimmed;
|
|
}
|
|
|
|
return list;
|
|
};
|
|
}
|
|
|
|
module.exports = ThreadListParticipants;
|