Skip to content
This repository has been archived by the owner on Oct 11, 2022. It is now read-only.

Commit

Permalink
Merge branch 'alpha' of github.com:withspectrum/spectrum into 2.6.3
Browse files Browse the repository at this point in the history
  • Loading branch information
brianlovin committed Jan 25, 2019
2 parents 4ba3dff + e5941bd commit 57d3394
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 23 deletions.
60 changes: 47 additions & 13 deletions src/components/chatInput/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import {
StyledMentionSuggestion,
SuggestionsWrapper,
MentionUsername,
MentionContent,
MentionName,
} from './style';
import sendMessage from 'shared/graphql/mutations/message/sendMessage';
import sendDirectMessage from 'shared/graphql/mutations/message/sendDirectMessage';
Expand All @@ -38,8 +40,11 @@ import { ESC, BACKSPACE, DELETE } from 'src/helpers/keycodes';

const MentionSuggestion = ({ entry, search, focused }) => (
<StyledMentionSuggestion focused={focused}>
<UserAvatar size={24} user={entry} />
<MentionUsername>{entry.username}</MentionUsername>
<UserAvatar size={32} user={entry} />
<MentionContent>
<MentionName focused={focused}>{entry.name}</MentionName>
<MentionUsername focused={focused}>@{entry.username}</MentionUsername>
</MentionContent>
</StyledMentionSuggestion>
);

Expand Down Expand Up @@ -292,21 +297,40 @@ const ChatInput = (props: Props) => {
);
};

const sortSuggestions = (a, b, queryString) => {
const aUsernameIndex = a.username.indexOf(queryString || '');
const bUsernameIndex = b.username.indexOf(queryString || '');
const aNameIndex = a.filterName.indexOf(queryString || '');
const bNameIndex = b.filterName.indexOf(queryString || '');
if (aNameIndex === 0) return -1;
if (aUsernameIndex === 0) return -1;
if (aNameIndex === 0) return -1;
if (aUsernameIndex === 0) return -1;
return aNameIndex - bNameIndex || aUsernameIndex - bUsernameIndex;
};

const searchUsers = async (queryString, callback) => {
const filteredParticipants = props.participants
? props.participants
.filter(Boolean)
.filter(
participant => participant.username.indexOf(queryString || '') > -1
)
.sort(
(a, b) =>
a.username.indexOf(queryString || '') -
b.username.indexOf(queryString || '')
)
.filter(participant => {
return (
participant.username &&
(participant.username.indexOf(queryString || '') > -1 ||
participant.filterName.indexOf(queryString || '') > -1)
);
})
.sort((a, b) => {
return sortSuggestions(a, b, queryString);
})
.slice(0, 8)
: [];

callback(filteredParticipants);
if (!queryString || queryString.length === 0) return;

if (!queryString || queryString.length === 0)
return callback(filteredParticipants);

const {
data: { search },
} = await props.client.query({
Expand All @@ -316,31 +340,40 @@ const ChatInput = (props: Props) => {
type: 'USERS',
},
});
if (!search || !search.searchResultsConnection) return;

if (!search || !search.searchResultsConnection) {
if (filteredParticipants && filteredParticipants.length > 0)
return filteredParticipants;
return;
}

let searchUsers = search.searchResultsConnection.edges
.filter(Boolean)
.filter(edge => edge.node.username)
.map(edge => {
const user = edge.node;
return {
...user,
id: user.username,
display: user.username,
username: user.username,
filterName: user.name.toLowerCase(),
};
});

// Prepend the filtered participants in case a user is tabbing down right now
const fullResults = [...filteredParticipants, ...searchUsers];
const uniqueResults = [];
const done = [];

fullResults.forEach(item => {
if (done.indexOf(item.username) === -1) {
uniqueResults.push(item);
done.push(item.username);
}
});

callback(uniqueResults);
return callback(uniqueResults.slice(0, 8));
};

const networkDisabled =
Expand Down Expand Up @@ -414,6 +447,7 @@ const ChatInput = (props: Props) => {
<Mention
trigger="@"
data={searchUsers}
appendSpaceOnAdd={true}
renderSuggestion={(
entry,
search,
Expand Down
32 changes: 24 additions & 8 deletions src/components/chatInput/style.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,10 @@ const MentionsInputStyle = {
suggestions: {
list: {
backgroundColor: theme.bg.default,
boxShadow: '1px 0 8px rgba(0,0,0,0.08)',
boxShadow: '1px 0 12px rgba(0,0,0,0.12)',
borderRadius: '4px',
overflow: 'hidden',
bottom: '24px',
bottom: '28px',
position: 'absolute',
},
},
Expand Down Expand Up @@ -349,17 +349,33 @@ export const MarkdownHint = styled.div`

export const StyledMentionSuggestion = styled.div`
display: flex;
padding: 4px 8px;
font-size: 14px;
font-weight: 500;
color: ${props => (props.focused ? theme.brand.default : theme.text.default)};
padding: 8px 12px;
align-items: center;
background: ${props => (props.focused ? theme.brand.wash : theme.bg.default)};
min-width: 156px;
line-height: 1.3;
border-bottom: 1px solid ${theme.bg.border};
`;

export const MentionContent = styled.div`
display: flex;
flex-direction: column;
`;

export const MentionName = styled.span`
margin-left: 12px;
width: calc(184px - 62px);
${Truncate};
font-size: 14px;
font-weight: 500;
color: ${props => (props.focused ? theme.brand.default : theme.text.default)};
`;

export const MentionUsername = styled.span`
margin-left: 8px;
width: calc(156px - 62px);
margin-left: 12px;
font-size: 13px;
font-weight: 400;
width: calc(184px - 62px);
${Truncate};
color: ${props => (props.focused ? theme.brand.default : theme.text.alt)};
`;
8 changes: 8 additions & 0 deletions src/views/thread/components/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,14 @@ class MessagesWithData extends React.Component<Props, State> {
componentDidMount() {
this.subscribe();

if (
this.props.data &&
this.props.data.thread &&
this.props.onMessagesLoaded
) {
this.props.onMessagesLoaded(this.props.data.thread);
}

if (this.shouldForceScrollToBottom()) {
return setTimeout(() => this.props.forceScrollToBottom());
}
Expand Down
16 changes: 14 additions & 2 deletions src/views/thread/container.js
Original file line number Diff line number Diff line change
Expand Up @@ -401,14 +401,26 @@ class ThreadContainer extends React.Component<Props, State> {

updateThreadParticipants = thread => {
const { messageConnection, author } = thread;
if (!messageConnection || messageConnection.edges.length === 0) return;

if (!messageConnection || messageConnection.edges.length === 0)
return this.setState({
participants: [
{ ...author.user, filterName: author.user.name.toLowerCase() },
],
});

const participants = messageConnection.edges
.map(edge => edge.node)
.map(node => node.author.user);

const participantsWithAuthor = [...participants, author.user]
.filter((user, index, array) => array.indexOf(user) === index)
.map(user => ({ ...user, id: user.username, display: user.username }));
.map(user => ({
...user,
id: user.username,
display: user.username,
filterName: user.name.toLowerCase(),
}));

return this.setState({ participants: participantsWithAuthor });
};
Expand Down

0 comments on commit 57d3394

Please sign in to comment.