Skip to content
This repository was archived by the owner on Oct 11, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion athena/utils/push-notifications/notification-formatting.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import onlyContainsEmoji from 'shared/only-contains-emoji';
import sentencify from 'shared/sentencify';
import { short as timeDifferenceShort } from 'shared/time-difference';
import { timeDifferenceShort } from 'shared/time-difference';
import sortByDate from 'shared/sort-by-date';
import { toState, toPlainText } from 'shared/draft-utils';

Expand Down
7 changes: 3 additions & 4 deletions mobile/components/Avatar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,14 @@ import { AvatarImage } from './style';

type AvatarProps = {|
src: string,
size: number,
radius: number,
size?: number,
onPress?: Function,
style?: Object,
|};

class Avatar extends Component<AvatarProps> {
render() {
const { src, size, radius, onPress, style } = this.props;
const { src, size, onPress, style } = this.props;
let source = src ? { uri: src } : {};

return (
Expand All @@ -27,7 +26,7 @@ class Avatar extends Component<AvatarProps> {
<TouchableHighlight onPress={onPress}>{children}</TouchableHighlight>
)}
>
<AvatarImage source={source} size={size} radius={radius} style={style} />
<AvatarImage source={source} size={size} style={style} />
</ConditionalWrap>
);
}
Expand Down
2 changes: 1 addition & 1 deletion mobile/components/Avatar/style.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ export const AvatarImage = styled.Image`
background-color: ${props => props.theme.bg.border};
width: ${props => (props.size ? `${props.size}px` : '30px')};
height: ${props => (props.size ? `${props.size}px` : '30px')};
border-radius: ${props => (props.radius ? `${props.radius}px` : '15px')};
border-radius: ${props => (props.size ? `${props.size / 2}px` : '15px')};
`;
6 changes: 6 additions & 0 deletions mobile/components/Flex/Column.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// @flow
import styled from 'styled-components/native';

export default styled.View`
flex-direction: column;
`;
6 changes: 6 additions & 0 deletions mobile/components/Flex/Row.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// @flow
import styled from 'styled-components/native';

export default styled.View`
flex-direction: row;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Added <Row /> and <Column /> components

`;
7 changes: 6 additions & 1 deletion mobile/components/Message/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@ const Message = ({ message, me }: Props) => {
case 'draftjs': {
return (
<Bubble me={me}>
<Text color={me ? '#FFFFFF' : '#000000'}>{body}</Text>
<Text
style={{ marginTop: 0, marginBottom: 0 }}
color={me ? '#FFFFFF' : '#000000'}
>
{body}
</Text>
</Bubble>
);
}
Expand Down
24 changes: 18 additions & 6 deletions mobile/components/Messages/index.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
// @flow
import React, { Fragment } from 'react';
import { View } from 'react-native';
import { View, ScrollView } from 'react-native';
import { Query } from 'react-apollo';
import { withNavigation } from 'react-navigation';
import compose from 'recompose/compose';
import { getCurrentUserQuery } from '../../../shared/graphql/queries/user/getUser';
import viewNetworkHandler from '../ViewNetworkHandler';
import Text from '../Text';
import Message from '../Message';
import InfiniteList from '../InfiniteList';
import { ThreadMargin } from '../../views/Thread/style';
import { sortAndGroupMessages } from '../../../shared/clients/group-messages';
import { convertTimestampToDate } from '../../../src/helpers/utils';

import RoboText from './RoboText';
import Author from './Author';

import type { FlatListProps } from 'react-native';
import type { Navigation } from 'react-navigation';
import type { ThreadMessageConnectionType } from '../../../shared/graphql/fragments/thread/threadMessageConnection.js';
import type { ThreadParticipantType } from '../../../shared/graphql/fragments/thread/threadParticipant';

type Props = {
...$Exact<FlatListProps>,
isLoading: boolean,
hasError: boolean,
navigation: Navigation,
Expand All @@ -30,7 +33,13 @@ type Props = {

class Messages extends React.Component<Props> {
render() {
const { data, isLoading, hasError, navigation } = this.props;
const {
data,
isLoading,
hasError,
navigation,
...flatListProps
} = this.props;

if (data.messageConnection && data.messageConnection) {
const messages = sortAndGroupMessages(
Expand All @@ -45,8 +54,11 @@ class Messages extends React.Component<Props> {
return (
<Query query={getCurrentUserQuery}>
{({ data: { user: currentUser } }) => (
<Fragment>
{messages.map((group, i) => {
<InfiniteList
{...flatListProps}
data={messages}
keyExtractor={item => item[0].id}
renderItem={({ item: group, index: i }) => {
if (group.length === 0) return null;

const initialMessage = group[0];
Expand Down Expand Up @@ -122,8 +134,8 @@ class Messages extends React.Component<Props> {
</ThreadMargin>
</View>
);
})}
</Fragment>
}}
/>
)}
</Query>
);
Expand Down
7 changes: 4 additions & 3 deletions mobile/components/Text/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@ const monospaceFont = Platform.OS === 'android' ? 'monospace' : 'Menlo';

const Text: ComponentType<Props> = styled.Text`
${(props: Props) => props.type && human[`${props.type}Object`]}
${(props: Props) =>
props.type &&
`margin-top: ${human[`${props.type}Object`].lineHeight * 0.35};`}
${(props: Props) => {
const type = props.type || 'body';
return `margin-top: ${human[`${type}Object`].lineHeight * 0.35};`;
}}
${(props: Props) => props.bold && 'font-weight: bold;'}
${(props: Props) => props.italic && 'font-style: italic;'}
${(props: Props) => props.underline && 'text-decoration-line: underline;'}
Expand Down
110 changes: 110 additions & 0 deletions mobile/views/DirectMessageThread/components/DirectMessageThread.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// @flow
import React, { Fragment } from 'react';
import { View } from 'react-native';
import compose from 'recompose/compose';
import { Query } from 'react-apollo';
import Text from '../../../components/Text';
import ChatInput from '../../../components/ChatInput';
import Messages from '../../../components/Messages';
import Avatar from '../../../components/Avatar';
import Column from '../../../components/Flex/Column';
import Row from '../../../components/Flex/Row';
import ViewNetworkHandler, {
type ViewNetworkHandlerProps,
} from '../../../components/ViewNetworkHandler';

import sentencify from '../../../../shared/sentencify';
import getDirectMessageThread, {
type GetDirectMessageThreadType,
} from '../../../../shared/graphql/queries/directMessageThread/getDirectMessageThread';
import getDirectMessageThreadMessageConnection from '../../../../shared/graphql/queries/directMessageThread/getDirectMessageThreadMessageConnection';
import type { GetUserType } from '../../../../shared/graphql/queries/user/getUser';
import sendDirectMessage from '../../../../shared/graphql/mutations/message/sendDirectMessage';

import type { DirectMessageThreadInfoType } from '../../../../shared/graphql/fragments/directMessageThread/directMessageThreadInfo';

const DirectMessageThreadMessages = getDirectMessageThreadMessageConnection(
Messages
);

type Props = {
...$Exact<ViewNetworkHandlerProps>,
id: string,
sendDirectMessage: Function,
currentUser: GetUserType,
data: {
directMessageThread?: GetDirectMessageThreadType,
},
};

class DirectMessageThread extends React.Component<Props> {
sendMessage = text => {
if (!this.props.data.directMessageThread) return;
this.props.sendDirectMessage({
threadId: this.props.data.directMessageThread.id,
threadType: 'directMessageThread',
messageType: 'text',
content: {
body: text,
},
});
};

render() {
const {
isLoading,
hasError,
data: { directMessageThread },
currentUser,
} = this.props;

if (directMessageThread) {
const participants = directMessageThread.participants.filter(
({ userId }) => userId !== currentUser.id
);
return (
<View style={{ flex: 1 }}>
<DirectMessageThreadMessages
id={directMessageThread.id}
ListHeaderComponent={() => (
<Column
style={{
alignItems: 'center',
marginTop: 32,
marginBottom: 32,
marginRight: 8,
marginLeft: 8,
}}
>
<Row>
{participants.map(({ profilePhoto, id }) => (
<Avatar
src={profilePhoto}
key={id}
size={60}
style={{ marginRight: 4, marginLeft: 4 }}
/>
))}
</Row>
<Text type="title3" bold>
{sentencify(participants.map(({ name }) => name))}
</Text>
</Column>
)}
/>
<ChatInput onSubmit={this.sendMessage} />
</View>
);
}

if (isLoading) return <Text>Loading...</Text>;
if (hasError) return <Text>Error :(</Text>;
return null;
}
}

export default compose(
ViewNetworkHandler,
sendDirectMessage,
getDirectMessageThread
)(DirectMessageThread);
48 changes: 48 additions & 0 deletions mobile/views/DirectMessageThread/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// @flow
import React from 'react';
import compose from 'recompose/compose';
import idx from 'idx';
import Text from '../../components/Text';
import ViewNetworkHandler, {
type ViewNetworkHandlerProps,
} from '../../components/ViewNetworkHandler';

import {
getCurrentUser,
type GetUserType,
} from '../../../shared/graphql/queries/user/getUser';

import DirectMessageThread from './components/DirectMessageThread';
import { Wrapper } from './style';

type Props = {
...$Exact<ViewNetworkHandlerProps>,
data: {
user?: GetUserType,
},
navigation?: {
state: {
params: {
id: string,
},
},
},
};

class DirectMessageThreadView extends React.Component<Props> {
render() {
const id = idx(this.props, props => props.navigation.state.params.id);
if (!id) return <Text>Non-existant DM thread</Text>;
if (!this.props.data.user) return null;
return (
<Wrapper>
{/* TODO(@mxstbr): We have to pass currentUser here because otherwise the sendDirectMessage mutation doesn't work. We should not make that a requirement. */}
<DirectMessageThread currentUser={this.props.data.user} id={id} />
</Wrapper>
);
}
}

export default compose(ViewNetworkHandler, getCurrentUser)(
DirectMessageThreadView
);
7 changes: 7 additions & 0 deletions mobile/views/DirectMessageThread/style.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// @flow
import styled from 'styled-components/native';

export const Wrapper = styled.View`
background-color: ${props => props.theme.bg.default};
flex: 1;
`;
Loading