Skip to content

Commit

Permalink
Merge pull request #44 from aimeex3/hack
Browse files Browse the repository at this point in the history
feat(mention): add @Moderators and @here
  • Loading branch information
aimeex3 authored May 1, 2020
2 parents 9befa32 + b276404 commit 613a131
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 30 deletions.
41 changes: 28 additions & 13 deletions src/components/ComposerQuill/composer.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class Composer extends React.Component {
bindings,
},
mention: {
dataAttributes: ['displayName', 'objectType', 'src'],
dataAttributes: ['displayName', 'objectType', 'src', 'items', 'secondary'],
defaultMenuOrientation: 'top',
mentionDenotationChars: ['@'],
onSelect: this.handleMentionSelect,
Expand Down Expand Up @@ -219,6 +219,7 @@ class Composer extends React.Component {
object.groupMentions = mentioned.group;
}

object.mentionType = mentioned.mentionType;
// sends the message, if it succeeded then clear the composer
if (send(object)) {
// clear the composer and reset the draft
Expand Down Expand Up @@ -286,22 +287,36 @@ class Composer extends React.Component {

try {
const participants = mentions.participants.current;
const copy = {...item};
const name = item.displayName;
const first = getFirstName(name);
let sanitizedItem;
const sanitizeMention = (mentionItem) => {
const copy = {...mentionItem};
const name = mentionItem.displayName;
const first = getFirstName(name);

// show just the first name unless someone else has the same first name
// check how many other participants have the same first name
const duplicates = participants.reduce((sum, participant) => {
const given = getFirstName(participant.displayName);
// show just the first name unless someone else has the same first name
// check how many other participants have the same first name
const duplicates = participants.reduce((sum, participant) => {
const given = getFirstName(participant.displayName);

return first === given ? sum + 1 : sum;
}, 0);
return first === given ? sum + 1 : sum;
}, 0);

// if there is more than one of you, then show full name instead
copy.value = duplicates > 1 ? name : first;
// if there is more than one of you, then show full name instead
copy.value = duplicates > 1 ? name : first;

insertItem(copy);
return copy;
};

if (item.items) {
let modItems = JSON.parse(item.items);

modItems = modItems.map(sanitizeMention);
sanitizedItem = {...item, items: JSON.stringify(modItems), value: item.displayName};
} else {
sanitizedItem = sanitizeMention(item);
}

insertItem(sanitizedItem);
} catch (e) {
if (isFunction(onError)) {
onError('QuillComposer', 'handleMentionSelect', e);
Expand Down
2 changes: 1 addition & 1 deletion src/components/ComposerQuill/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
border-radius: 1000px;
margin: auto 10px;

&.all {
&.group-mention {
font-size: .9rem;
}
}
Expand Down
43 changes: 31 additions & 12 deletions src/components/ComposerQuill/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ const uuidRegex = /[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[

// regexes that matches the mention placeholder
// this one matches the whole placeholder
const mentionRegexMatchWhole = /(@{.+?_(?:groupMention|person)_(?:all|[\w-]{36})})/;
const mentionRegexMatchWhole = /(@{.+?_(?:groupMention|person)_(?:all|moderators|here|[\w-]{36})})/;
// this one matches the individual values
const mentionRegexMatchValues = /@{(.+?)_(groupMention|person)_(all|[\w-]{36})}/g;
const mentionRegexMatchValues = /@{(.+?)_(groupMention|person)_(all|moderators|here|[\w-]{36})}/g;

// returns the mention placeholder string
// WARNING: this string should match the regex right above this
Expand Down Expand Up @@ -98,11 +98,18 @@ export function getQuillText(quill) {
export function replaceMentions(text, mentions) {
try {
return text.replace(mentionRegexMatchValues, (match, name, type, id) => {
let sb;
let sb = '';

if (type === 'groupMention') {
// check if an all mention was inserted to the composer
if (id === 'all' && mentions.group.some((mention) => mention.groupType === id)) {
if (id === 'moderators' || id === 'here') {
mentions.people.forEach((mention, i) => {
sb += `<spark-mention data-object-type='${mention.objectType}' data-object-id='${mention.id}'>${mention.name}</spark-mention>`;
if (i < mentions.people.length - 1) {
sb += ', ';
}
});
} else if (id === 'all' && mentions.group.some((mention) => mention.groupType === id)) {
sb = `<spark-mention data-object-type='${type}' data-group-type='${id}'>${name}</spark-mention>`;
}
} else if (type === 'person') {
Expand Down Expand Up @@ -140,11 +147,28 @@ export function getMentions(quill) {
id: mention.id,
objectType: mention.objectType,
});
mentions.mentionType = 'person';
} else if (mention.objectType === 'groupMention' && mention.id === 'all') {
mentions.group.push({
groupType: mention.id,
objectType: mention.objectType,
});
mentions.mentionType = mention.id;
} else if (
mention.objectType === 'groupMention' &&
mention.items &&
(mention.id === 'moderators' || mention.id === 'here')
) {
mentions.mentionType = mention.id;
const list = JSON.parse(mention.items);

list.forEach((person) => {
mentions.people.push({
id: person.id,
objectType: person.objectType,
name: person.value,
});
});
}
}
});
Expand All @@ -169,9 +193,9 @@ export function buildMentionAvatar(item) {
// otherwise we build it ourself
let initials;

if (id === 'all') {
if (id === 'all' || id === 'moderators' || id === 'here') {
// avatar is a circle @ for all
classes += ' all';
classes += ' group-mention';
initials = '@';
} else {
// use the initials of the name as the avatar
Expand All @@ -193,14 +217,9 @@ export function buildMentionAvatar(item) {

// build the text element for mention item
export function buildMentionText(item) {
const {id, displayName} = item;
let secondary;
const {displayName, secondary} = item;
let text = '';

if (id === 'all') {
secondary = 'Mention everyone in this space';
}

text += "<div class='ql-mention-item-text'>";
text += "<div class='ql-mention-item-text-primary'>";
text += displayName;
Expand Down
35 changes: 31 additions & 4 deletions src/index.stories.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,26 @@
import React, {useMemo, useState, useRef} from 'react';
import uuid from 'uuid';

import MessageComposer from './index.js';

import './styles.scss';

let ids = 1;
const users = [
{
id: 'all',
displayName: 'All',
objectType: 'groupMention',
},
{
id: 'here',
displayName: 'Here',
objectType: 'groupMention',
},
{
id: 'moderators',
displayName: 'Moderators',
objectType: 'groupMention',
},
{
displayName: 'Philip Fry',
},
Expand Down Expand Up @@ -46,14 +56,24 @@ const users = [
},
];

for (const user of users) {
const sanitizeUser = (user) => {
if (!user.id) {
// eslint-disable-next-line no-plusplus
user.id = ids++;
// eslint-disable-next-line no-param-reassign
user.id = uuid.v4();
}
if (!user.objectType) {
// eslint-disable-next-line no-param-reassign
user.objectType = 'person';
}
};

for (const user of users) {
sanitizeUser(user);
if (user.items) {
for (const person of user.items) {
sanitizeUser(person);
}
}
}

let mentions = {
Expand Down Expand Up @@ -82,6 +102,13 @@ let mentions = {
},
getDisplay: (user) => (user.objectType === 'person' ? user.displayName.split(' ')[0] : user.displayName),
};
// insert presence items
let items = [users[3], users[4], users[5]];

users[1].items = JSON.stringify(items);
// insert moderators
items = [users[5], users[6], users[7]];
users[2].items = JSON.stringify(items);

const spaces = [];
const setValue = (v, num) => {
Expand Down

0 comments on commit 613a131

Please sign in to comment.