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

Commit cec409d

Browse files
authored
Merge pull request #4591 from withspectrum/2.6.4
2.6.4
2 parents bece936 + 24c10e5 commit cec409d

File tree

12 files changed

+257
-215
lines changed

12 files changed

+257
-215
lines changed

api/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
"find-with-regex": "^1.1.3",
5151
"flow-typed": "^2.5.1",
5252
"graphql": "0.13.x",
53-
"graphql-cost-analysis": "^1.0.2",
53+
"graphql-cost-analysis": "^1.0.3",
5454
"graphql-date": "^1.0.3",
5555
"graphql-depth-limit": "^1.1.0",
5656
"graphql-log": "^0.1.3",

api/utils/is-spectrum-url.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ export default (url: string): boolean => {
1616
const { hostname, protocol } = new URL(url);
1717
// hostname might be spectrum.chat or subdomain.spectrum.chat, so we use .endsWith
1818
// We don't just check .contains because otherwise folks could make spectrum.chat.mydomain.com
19-
const IS_SPECTRUM_URL = hostname.endsWith('.spectrum.chat');
19+
const IS_SPECTRUM_URL =
20+
hostname === 'spectrum.chat' || hostname === 'alpha.spectrum.chat';
2021
const IS_LOCALHOST = hostname === 'localhost';
2122
const IS_HTTP = protocol === 'https:' || protocol === 'http:';
2223
// Make sure the passed redirect URL is a spectrum.chat one or (in development) localhost

api/yarn.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4567,10 +4567,10 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6:
45674567
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00"
45684568
integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==
45694569

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

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "Spectrum",
3-
"version": "2.6.3",
3+
"version": "2.6.4",
44
"license": "BSD-3-Clause",
55
"devDependencies": {
66
"@babel/preset-flow": "^7.0.0",
@@ -87,7 +87,7 @@
8787
"draft-js-code-editor-plugin": "0.2.1",
8888
"draft-js-drag-n-drop-plugin": "^2.0.3",
8989
"draft-js-embed-plugin": "^1.2.0",
90-
"draft-js-export-markdown": "^1.2.2",
90+
"draft-js-export-markdown": "^1.3.0",
9191
"draft-js-focus-plugin": "^2.2.0",
9292
"draft-js-image-plugin": "^2.0.6",
9393
"draft-js-import-markdown": "^1.2.3",

src/components/chatInput/index.js

Lines changed: 15 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,11 @@
22
import * as React from 'react';
33
import compose from 'recompose/compose';
44
import { connect } from 'react-redux';
5-
import { Mention } from 'react-mentions';
6-
import { withApollo } from 'react-apollo';
75
import Icon from 'src/components/icons';
8-
import { FlexRow } from 'src/components/globals';
96
import { addToastWithTimeout } from 'src/actions/toasts';
107
import { openModal } from 'src/actions/modals';
118
import { replyToMessage } from 'src/actions/message';
129
import { withCurrentUser } from 'src/components/withCurrentUser';
13-
import { UserAvatar } from 'src/components/avatar';
1410
import {
1511
Form,
1612
ChatInputContainer,
@@ -23,30 +19,13 @@ import {
2319
Preformatted,
2420
PreviewWrapper,
2521
RemovePreviewButton,
26-
StyledMentionSuggestion,
27-
SuggestionsWrapper,
28-
MentionUsername,
29-
MentionContent,
30-
MentionName,
3122
} from './style';
3223
import sendMessage from 'shared/graphql/mutations/message/sendMessage';
3324
import sendDirectMessage from 'shared/graphql/mutations/message/sendDirectMessage';
34-
import { searchUsersQuery } from 'shared/graphql/queries/search/searchUsers';
3525
import { getMessageById } from 'shared/graphql/queries/message/getMessage';
3626
import MediaUploader from './components/mediaUploader';
3727
import { QuotedMessage as QuotedMessageComponent } from '../message/view';
3828
import type { Dispatch } from 'redux';
39-
import { ESC, BACKSPACE, DELETE } from 'src/helpers/keycodes';
40-
41-
const MentionSuggestion = ({ entry, search, focused }) => (
42-
<StyledMentionSuggestion focused={focused}>
43-
<UserAvatar size={32} user={entry} />
44-
<MentionContent>
45-
<MentionName focused={focused}>{entry.name}</MentionName>
46-
<MentionUsername focused={focused}>@{entry.username}</MentionUsername>
47-
</MentionContent>
48-
</StyledMentionSuggestion>
49-
);
5029

5130
const QuotedMessage = connect()(
5231
getMessageById(props => {
@@ -93,6 +72,16 @@ type Props = {
9372
onBlur: ?Function,
9473
};
9574

75+
export const cleanSuggestionUserObject = (user: ?Object) => {
76+
if (!user) return null;
77+
return {
78+
...user,
79+
id: user.username,
80+
display: user.username,
81+
filterName: user.name.toLowerCase(),
82+
};
83+
};
84+
9685
// $FlowFixMe
9786
const ChatInput = (props: Props) => {
9887
const cacheKey = `last-content-${props.thread}`;
@@ -243,7 +232,9 @@ const ChatInput = (props: Props) => {
243232

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

246-
sendMessage({ body: text })
235+
// workaround react-mentions bug by replacing @[username] with @username
236+
// @see withspectrum/spectrum#4587
237+
sendMessage({ body: text.replace(/@\[([a-z0-9_-]+)\]/g, '@$1') })
247238
.then(() => {
248239
// If we're viewing a thread and the user sends a message as a non-member, we need to refetch the thread data
249240
if (
@@ -297,85 +288,6 @@ const ChatInput = (props: Props) => {
297288
);
298289
};
299290

300-
const sortSuggestions = (a, b, queryString) => {
301-
const aUsernameIndex = a.username.indexOf(queryString || '');
302-
const bUsernameIndex = b.username.indexOf(queryString || '');
303-
const aNameIndex = a.filterName.indexOf(queryString || '');
304-
const bNameIndex = b.filterName.indexOf(queryString || '');
305-
if (aNameIndex === 0) return -1;
306-
if (aUsernameIndex === 0) return -1;
307-
if (aNameIndex === 0) return -1;
308-
if (aUsernameIndex === 0) return -1;
309-
return aNameIndex - bNameIndex || aUsernameIndex - bUsernameIndex;
310-
};
311-
312-
const searchUsers = async (queryString, callback) => {
313-
const filteredParticipants = props.participants
314-
? props.participants
315-
.filter(Boolean)
316-
.filter(participant => {
317-
return (
318-
participant.username &&
319-
(participant.username.indexOf(queryString || '') > -1 ||
320-
participant.filterName.indexOf(queryString || '') > -1)
321-
);
322-
})
323-
.sort((a, b) => {
324-
return sortSuggestions(a, b, queryString);
325-
})
326-
.slice(0, 8)
327-
: [];
328-
329-
callback(filteredParticipants);
330-
331-
if (!queryString || queryString.length === 0)
332-
return callback(filteredParticipants);
333-
334-
const {
335-
data: { search },
336-
} = await props.client.query({
337-
query: searchUsersQuery,
338-
variables: {
339-
queryString,
340-
type: 'USERS',
341-
},
342-
});
343-
344-
if (!search || !search.searchResultsConnection) {
345-
if (filteredParticipants && filteredParticipants.length > 0)
346-
return filteredParticipants;
347-
return;
348-
}
349-
350-
let searchUsers = search.searchResultsConnection.edges
351-
.filter(Boolean)
352-
.filter(edge => edge.node.username)
353-
.map(edge => {
354-
const user = edge.node;
355-
return {
356-
...user,
357-
id: user.username,
358-
display: user.username,
359-
username: user.username,
360-
filterName: user.name.toLowerCase(),
361-
};
362-
});
363-
364-
// Prepend the filtered participants in case a user is tabbing down right now
365-
const fullResults = [...filteredParticipants, ...searchUsers];
366-
const uniqueResults = [];
367-
const done = [];
368-
369-
fullResults.forEach(item => {
370-
if (done.indexOf(item.username) === -1) {
371-
uniqueResults.push(item);
372-
done.push(item.username);
373-
}
374-
});
375-
376-
return callback(uniqueResults.slice(0, 8));
377-
};
378-
379291
const networkDisabled =
380292
!props.networkOnline ||
381293
(props.websocketConnection !== 'connected' &&
@@ -443,28 +355,8 @@ const ChatInput = (props: Props) => {
443355
if (props.onRef) props.onRef(node);
444356
setInputRef(node);
445357
}}
446-
>
447-
<Mention
448-
trigger="@"
449-
data={searchUsers}
450-
appendSpaceOnAdd={true}
451-
renderSuggestion={(
452-
entry,
453-
search,
454-
highlightedDisplay,
455-
index,
456-
focused
457-
) => (
458-
<MentionSuggestion
459-
entry={entry}
460-
highlightedDisplay={highlightedDisplay}
461-
focused={focused}
462-
search={search}
463-
index={index}
464-
/>
465-
)}
466-
/>
467-
</Input>
358+
staticSuggestions={props.participants}
359+
/>
468360
</InputWrapper>
469361
<SendButton
470362
data-cy="chat-input-send-button"
@@ -494,7 +386,6 @@ const map = (state, ownProps) => ({
494386

495387
export default compose(
496388
withCurrentUser,
497-
withApollo,
498389
sendMessage,
499390
sendDirectMessage,
500391
// $FlowIssue

src/components/chatInput/style.js

Lines changed: 3 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
// @flow
2-
import React from 'react';
32
import theme from 'shared/theme';
43
import styled, { css } from 'styled-components';
5-
import { MentionsInput } from 'react-mentions';
4+
import MentionsInput from '../mentionsInput';
65
import { IconButton } from '../buttons';
76
import { QuoteWrapper } from '../message/style';
87
import {
@@ -11,7 +10,6 @@ import {
1110
Transition,
1211
zIndex,
1312
monoStack,
14-
Truncate,
1513
} from 'src/components/globals';
1614

1715
export const ChatInputContainer = styled(FlexRow)`
@@ -98,35 +96,12 @@ export const InputWrapper = styled.div`
9896
}
9997
`;
10098

101-
const MentionsInputStyle = {
102-
suggestions: {
103-
list: {
104-
backgroundColor: theme.bg.default,
105-
boxShadow: '1px 0 12px rgba(0,0,0,0.12)',
106-
borderRadius: '4px',
107-
overflow: 'hidden',
108-
bottom: '28px',
109-
position: 'absolute',
110-
},
111-
},
112-
};
113-
114-
export const SuggestionsWrapper = styled.div``;
115-
116-
export const Input = styled(
117-
({ hasAttachment, networkDisabled, dataCy, ...rest }) => (
118-
<MentionsInput
119-
style={MentionsInputStyle}
120-
displayTransform={username => `@${username}`}
121-
{...rest}
122-
/>
123-
)
124-
).attrs({
99+
export const Input = styled(MentionsInput).attrs({
100+
dataCy: props => props.dataCy || 'chat-input',
125101
spellCheck: true,
126102
autoCapitalize: 'sentences',
127103
autoComplete: 'on',
128104
autoCorrect: 'on',
129-
'data-cy': props => props.dataCy || 'chat-input',
130105
})`
131106
font-size: 15px;
132107
font-weight: 400;
@@ -346,36 +321,3 @@ export const MarkdownHint = styled.div`
346321
display: none;
347322
}
348323
`;
349-
350-
export const StyledMentionSuggestion = styled.div`
351-
display: flex;
352-
padding: 8px 12px;
353-
align-items: center;
354-
background: ${props => (props.focused ? theme.brand.wash : theme.bg.default)};
355-
min-width: 156px;
356-
line-height: 1.3;
357-
border-bottom: 1px solid ${theme.bg.border};
358-
`;
359-
360-
export const MentionContent = styled.div`
361-
display: flex;
362-
flex-direction: column;
363-
`;
364-
365-
export const MentionName = styled.span`
366-
margin-left: 12px;
367-
width: calc(184px - 62px);
368-
${Truncate};
369-
font-size: 14px;
370-
font-weight: 500;
371-
color: ${props => (props.focused ? theme.brand.default : theme.text.default)};
372-
`;
373-
374-
export const MentionUsername = styled.span`
375-
margin-left: 12px;
376-
font-size: 13px;
377-
font-weight: 400;
378-
width: calc(184px - 62px);
379-
${Truncate};
380-
color: ${props => (props.focused ? theme.brand.default : theme.text.alt)};
381-
`;

0 commit comments

Comments
 (0)