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

Commit

Permalink
Merge pull request #4591 from withspectrum/2.6.4
Browse files Browse the repository at this point in the history
2.6.4
  • Loading branch information
brianlovin authored Jan 28, 2019
2 parents bece936 + 24c10e5 commit cec409d
Show file tree
Hide file tree
Showing 12 changed files with 257 additions and 215 deletions.
2 changes: 1 addition & 1 deletion api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"find-with-regex": "^1.1.3",
"flow-typed": "^2.5.1",
"graphql": "0.13.x",
"graphql-cost-analysis": "^1.0.2",
"graphql-cost-analysis": "^1.0.3",
"graphql-date": "^1.0.3",
"graphql-depth-limit": "^1.1.0",
"graphql-log": "^0.1.3",
Expand Down
3 changes: 2 additions & 1 deletion api/utils/is-spectrum-url.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ export default (url: string): boolean => {
const { hostname, protocol } = new URL(url);
// hostname might be spectrum.chat or subdomain.spectrum.chat, so we use .endsWith
// We don't just check .contains because otherwise folks could make spectrum.chat.mydomain.com
const IS_SPECTRUM_URL = hostname.endsWith('.spectrum.chat');
const IS_SPECTRUM_URL =
hostname === 'spectrum.chat' || hostname === 'alpha.spectrum.chat';
const IS_LOCALHOST = hostname === 'localhost';
const IS_HTTP = protocol === 'https:' || protocol === 'http:';
// Make sure the passed redirect URL is a spectrum.chat one or (in development) localhost
Expand Down
8 changes: 4 additions & 4 deletions api/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4567,10 +4567,10 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6:
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00"
integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==

graphql-cost-analysis@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/graphql-cost-analysis/-/graphql-cost-analysis-1.0.2.tgz#680f7b99137e5e21f279f76e01f779955258de0a"
integrity sha512-U6TaSSarx4WbCwT0520xsGvhNwYu5GWfn4bEHMiVgdWvWvdfscVp0n8zShTwzoEoO0gEYT2fXTg1O2KadDbg/A==
graphql-cost-analysis@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/graphql-cost-analysis/-/graphql-cost-analysis-1.0.3.tgz#25b97c8e638c7e538af5ba9bcf6012cda74420ce"
integrity sha512-2kogZrc3iPVW5Lf2cSadVfufNx440XMoqKbMjNRi96HV80jCk9is1AI7CwizT5CSGzKlsnGQmaSqjeR1dJB0Gw==
dependencies:
selectn "^1.1.2"

Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "Spectrum",
"version": "2.6.3",
"version": "2.6.4",
"license": "BSD-3-Clause",
"devDependencies": {
"@babel/preset-flow": "^7.0.0",
Expand Down Expand Up @@ -87,7 +87,7 @@
"draft-js-code-editor-plugin": "0.2.1",
"draft-js-drag-n-drop-plugin": "^2.0.3",
"draft-js-embed-plugin": "^1.2.0",
"draft-js-export-markdown": "^1.2.2",
"draft-js-export-markdown": "^1.3.0",
"draft-js-focus-plugin": "^2.2.0",
"draft-js-image-plugin": "^2.0.6",
"draft-js-import-markdown": "^1.2.3",
Expand Down
139 changes: 15 additions & 124 deletions src/components/chatInput/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,11 @@
import * as React from 'react';
import compose from 'recompose/compose';
import { connect } from 'react-redux';
import { Mention } from 'react-mentions';
import { withApollo } from 'react-apollo';
import Icon from 'src/components/icons';
import { FlexRow } from 'src/components/globals';
import { addToastWithTimeout } from 'src/actions/toasts';
import { openModal } from 'src/actions/modals';
import { replyToMessage } from 'src/actions/message';
import { withCurrentUser } from 'src/components/withCurrentUser';
import { UserAvatar } from 'src/components/avatar';
import {
Form,
ChatInputContainer,
Expand All @@ -23,30 +19,13 @@ import {
Preformatted,
PreviewWrapper,
RemovePreviewButton,
StyledMentionSuggestion,
SuggestionsWrapper,
MentionUsername,
MentionContent,
MentionName,
} from './style';
import sendMessage from 'shared/graphql/mutations/message/sendMessage';
import sendDirectMessage from 'shared/graphql/mutations/message/sendDirectMessage';
import { searchUsersQuery } from 'shared/graphql/queries/search/searchUsers';
import { getMessageById } from 'shared/graphql/queries/message/getMessage';
import MediaUploader from './components/mediaUploader';
import { QuotedMessage as QuotedMessageComponent } from '../message/view';
import type { Dispatch } from 'redux';
import { ESC, BACKSPACE, DELETE } from 'src/helpers/keycodes';

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

const QuotedMessage = connect()(
getMessageById(props => {
Expand Down Expand Up @@ -93,6 +72,16 @@ type Props = {
onBlur: ?Function,
};

export const cleanSuggestionUserObject = (user: ?Object) => {
if (!user) return null;
return {
...user,
id: user.username,
display: user.username,
filterName: user.name.toLowerCase(),
};
};

// $FlowFixMe
const ChatInput = (props: Props) => {
const cacheKey = `last-content-${props.thread}`;
Expand Down Expand Up @@ -243,7 +232,9 @@ const ChatInput = (props: Props) => {

if (text.length === 0) return;

sendMessage({ body: text })
// workaround react-mentions bug by replacing @[username] with @username
// @see withspectrum/spectrum#4587
sendMessage({ body: text.replace(/@\[([a-z0-9_-]+)\]/g, '@$1') })
.then(() => {
// If we're viewing a thread and the user sends a message as a non-member, we need to refetch the thread data
if (
Expand Down Expand Up @@ -297,85 +288,6 @@ 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 => {
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 callback(filteredParticipants);

const {
data: { search },
} = await props.client.query({
query: searchUsersQuery,
variables: {
queryString,
type: 'USERS',
},
});

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);
}
});

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

const networkDisabled =
!props.networkOnline ||
(props.websocketConnection !== 'connected' &&
Expand Down Expand Up @@ -443,28 +355,8 @@ const ChatInput = (props: Props) => {
if (props.onRef) props.onRef(node);
setInputRef(node);
}}
>
<Mention
trigger="@"
data={searchUsers}
appendSpaceOnAdd={true}
renderSuggestion={(
entry,
search,
highlightedDisplay,
index,
focused
) => (
<MentionSuggestion
entry={entry}
highlightedDisplay={highlightedDisplay}
focused={focused}
search={search}
index={index}
/>
)}
/>
</Input>
staticSuggestions={props.participants}
/>
</InputWrapper>
<SendButton
data-cy="chat-input-send-button"
Expand Down Expand Up @@ -494,7 +386,6 @@ const map = (state, ownProps) => ({

export default compose(
withCurrentUser,
withApollo,
sendMessage,
sendDirectMessage,
// $FlowIssue
Expand Down
64 changes: 3 additions & 61 deletions src/components/chatInput/style.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
// @flow
import React from 'react';
import theme from 'shared/theme';
import styled, { css } from 'styled-components';
import { MentionsInput } from 'react-mentions';
import MentionsInput from '../mentionsInput';
import { IconButton } from '../buttons';
import { QuoteWrapper } from '../message/style';
import {
Expand All @@ -11,7 +10,6 @@ import {
Transition,
zIndex,
monoStack,
Truncate,
} from 'src/components/globals';

export const ChatInputContainer = styled(FlexRow)`
Expand Down Expand Up @@ -98,35 +96,12 @@ export const InputWrapper = styled.div`
}
`;

const MentionsInputStyle = {
suggestions: {
list: {
backgroundColor: theme.bg.default,
boxShadow: '1px 0 12px rgba(0,0,0,0.12)',
borderRadius: '4px',
overflow: 'hidden',
bottom: '28px',
position: 'absolute',
},
},
};

export const SuggestionsWrapper = styled.div``;

export const Input = styled(
({ hasAttachment, networkDisabled, dataCy, ...rest }) => (
<MentionsInput
style={MentionsInputStyle}
displayTransform={username => `@${username}`}
{...rest}
/>
)
).attrs({
export const Input = styled(MentionsInput).attrs({
dataCy: props => props.dataCy || 'chat-input',
spellCheck: true,
autoCapitalize: 'sentences',
autoComplete: 'on',
autoCorrect: 'on',
'data-cy': props => props.dataCy || 'chat-input',
})`
font-size: 15px;
font-weight: 400;
Expand Down Expand Up @@ -346,36 +321,3 @@ export const MarkdownHint = styled.div`
display: none;
}
`;

export const StyledMentionSuggestion = styled.div`
display: flex;
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: 12px;
font-size: 13px;
font-weight: 400;
width: calc(184px - 62px);
${Truncate};
color: ${props => (props.focused ? theme.brand.default : theme.text.alt)};
`;
Loading

0 comments on commit cec409d

Please sign in to comment.