diff --git a/src/common/Avatar.js b/src/common/Avatar.js
index a3b4720726c..2d79ed77567 100644
--- a/src/common/Avatar.js
+++ b/src/common/Avatar.js
@@ -28,7 +28,7 @@ class Avatar extends PureComponent {
status?: UserStatus,
realm: string,
shape: 'square' | 'rounded' | 'circle',
- onPress?: () => void,
+ onPress: () => void,
};
static defaultProps = {
diff --git a/src/common/ImageAvatar.js b/src/common/ImageAvatar.js
index ffbcc788fa8..cfba3b6d34a 100644
--- a/src/common/ImageAvatar.js
+++ b/src/common/ImageAvatar.js
@@ -10,8 +10,7 @@ export default class ImageAvatar extends PureComponent {
avatarUrl: string,
size: number,
shape: string,
- children: [],
- onPress?: () => void,
+ onPress: () => void,
};
static defaultProps = {
@@ -19,7 +18,7 @@ export default class ImageAvatar extends PureComponent {
};
render() {
- const { avatarUrl, size, shape, onPress, children } = this.props;
+ const { avatarUrl, size, shape, onPress } = this.props;
const touchableStyle = {
height: size,
width: size,
@@ -34,9 +33,8 @@ export default class ImageAvatar extends PureComponent {
style={touchableStyle}
source={{ uri: avatarUrl }}
resizeMode="cover"
- borderRadius={borderRadius}>
- {children}
-
+ borderRadius={borderRadius}
+ />
);
}
diff --git a/src/common/TextAvatar.js b/src/common/TextAvatar.js
index 7cc9f70a7dd..d39933911ee 100644
--- a/src/common/TextAvatar.js
+++ b/src/common/TextAvatar.js
@@ -1,5 +1,5 @@
/* @flow */
-import React from 'react';
+import React, { PureComponent } from 'react';
import { Text, StyleSheet, View } from 'react-native';
import { Touchable } from './';
@@ -25,34 +25,36 @@ const styles = StyleSheet.create({
},
});
-type Props = {
- name: string,
- size: number,
- shape: string,
- children: [],
- onPress?: () => void,
-};
-
-export default ({ name, size, status, shape, onPress, children }: Props) => {
- const frameSize = {
- height: size,
- width: size,
- borderRadius:
- shape === 'rounded' ? size / 8 : shape === 'circle' ? size / 2 : shape === 'square' ? 0 : 0,
- backgroundColor: colorHashFromName(name),
- };
- const textSize = {
- fontSize: size / 3,
+export default class TextAvatar extends PureComponent {
+ props: {
+ name: string,
+ size: number,
+ shape?: string,
+ onPress?: () => void,
};
- return (
-
-
-
- {initialsFromName(name)}
-
- {children}
-
-
- );
-};
+ render() {
+ const { name, size, shape, onPress } = this.props;
+
+ const frameSize = {
+ height: size,
+ width: size,
+ borderRadius:
+ shape === 'rounded' ? size / 8 : shape === 'circle' ? size / 2 : shape === 'square' ? 0 : 0,
+ backgroundColor: colorHashFromName(name),
+ };
+ const textSize = {
+ fontSize: size / 3,
+ };
+
+ return (
+
+
+
+ {initialsFromName(name)}
+
+
+
+ );
+ }
+}
diff --git a/src/conversations/ConversationGroup.js b/src/conversations/ConversationGroup.js
index 71fd5bc630e..cbda3b33f89 100644
--- a/src/conversations/ConversationGroup.js
+++ b/src/conversations/ConversationGroup.js
@@ -8,7 +8,7 @@ import { NULL_USER } from '../nullObjects';
import type { User, Narrow } from '../types';
import { normalizeRecipients } from '../utils/message';
import { isGroupNarrow } from '../utils/narrow';
-import { Avatar, RawLabel, Touchable, UnreadCount } from '../common';
+import { TextAvatar, RawLabel, Touchable, UnreadCount } from '../common';
import { BRAND_COLOR } from '../styles';
const styles = StyleSheet.create({
@@ -36,7 +36,7 @@ class ConversationGroup extends PureComponent {
email: string,
users: User[],
unreadCount: number,
- narrow?: Narrow,
+ narrow: Narrow,
onPress: (emails: string) => void,
};
@@ -57,7 +57,7 @@ class ConversationGroup extends PureComponent {
return (
-
+
void,
typingUsers?: TypingState,
- messages: Array,
- narrow: Narrow,
+ renderedMessages: any[],
};
export default class MessageList extends PureComponent {
@@ -49,25 +47,19 @@ export default class MessageList extends PureComponent {
singleFetchProgress,
onScroll,
typingUsers,
- messages,
- narrow,
+ renderedMessages,
} = this.props;
- const messageList = renderMessages({
- messages,
- narrow,
- });
-
// `headerIndices` tell the scroll view which components are headers
// and are eligible to be docked at the top of the view.
const headerIndices = [];
- for (let i = 0; i < messageList.length; i++) {
- const elem = messageList[i];
+ for (let i = 0; i < renderedMessages.length; i++) {
+ const elem = renderedMessages[i];
if (elem.props.type === 'header') {
headerIndices.push(i + 1);
}
if (elem.props.type === 'message') {
- messageList[i] = (
+ renderedMessages[i] = (
- {messageList}
+ {renderedMessages}
{!singleFetchProgress && fetchingNewer && }
{typingUsers && }
diff --git a/src/message/MessageListContainer.js b/src/message/MessageListContainer.js
index b74a65330a6..4489df4cf79 100644
--- a/src/message/MessageListContainer.js
+++ b/src/message/MessageListContainer.js
@@ -9,7 +9,7 @@ import {
getAuth,
getFlags,
getCurrentTypingUsers,
- getShownMessagesInActiveNarrow,
+ getRenderedMessages,
getActiveNarrow,
getCaughtUpForActiveNarrow,
} from '../selectors';
@@ -40,7 +40,7 @@ class MessageListContainer extends PureComponent {
fetchingOlder,
fetchingNewer,
typingUsers,
- messages,
+ renderedMessages,
narrow,
actions,
} = this.props;
@@ -52,7 +52,7 @@ class MessageListContainer extends PureComponent {
fetchingOlder={fetchingOlder}
fetchingNewer={fetchingNewer}
typingUsers={typingUsers}
- messages={messages}
+ renderedMessages={renderedMessages}
narrow={narrow}
actions={actions}
/>
@@ -67,7 +67,7 @@ export default connect(
fetchingOlder: state.chat.fetchingOlder,
fetchingNewer: state.chat.fetchingNewer,
typingUsers: getCurrentTypingUsers(state),
- messages: getShownMessagesInActiveNarrow(state),
+ renderedMessages: getRenderedMessages(state),
narrow: getActiveNarrow(state),
flags: getFlags(state),
auth: getAuth(state),
diff --git a/src/message/MessageListFlatList.js b/src/message/MessageListFlatList.js
index e44982bf673..ad9d6b6d0c1 100644
--- a/src/message/MessageListFlatList.js
+++ b/src/message/MessageListFlatList.js
@@ -7,7 +7,6 @@ import { nullFunction } from '../nullObjects';
import MessageContainer from './MessageContainer';
import TaggedView from '../native/TaggedView';
import renderMessages from './renderMessages';
-import { getFullUrl } from '../utils/url';
import {
constructActionButtons,
executeActionSheetAction,
@@ -72,32 +71,9 @@ class MessageList extends PureComponent {
render() {
const { styles } = this.context;
- const {
- auth,
- actions,
- subscriptions,
- users,
- messages,
- narrow,
- mute,
- doNarrow,
- flags,
- twentyFourHourTime,
- } = this.props;
+ const { messages, narrow } = this.props;
- const messageList = renderMessages({
- onLongPress: this.handleLongPress,
- onHeaderLongPress: this.handleHeaderLongPress,
- auth,
- actions,
- subscriptions,
- users,
- messages,
- narrow,
- mute,
- flags,
- twentyFourHourTime,
- });
+ const messageList = renderMessages(messages, narrow);
// `headerIndices` tell the scroll view which components are headers
// and are eligible to be docked at the top of the view.
@@ -128,14 +104,9 @@ class MessageList extends PureComponent {
keyExtractor={item => item.id}
renderItem={({ item }) =>
}
renderSectionHeader={({ section }) =>
diff --git a/src/message/__tests__/renderMessages-test.js b/src/message/__tests__/renderMessages-test.js
index ad645e5181c..026da541d8e 100644
--- a/src/message/__tests__/renderMessages-test.js
+++ b/src/message/__tests__/renderMessages-test.js
@@ -6,9 +6,7 @@ describe('renderMessages', () => {
const narrow = deepFreeze([]);
test('empty messages results in no rendered messages', () => {
- const props = deepFreeze({ messages: [] });
-
- const messageList = renderMessages(props);
+ const messageList = renderMessages([]);
expect(messageList).toEqual([]);
});
@@ -23,7 +21,7 @@ describe('renderMessages', () => {
const expectedComponentKeys = ['time123', 'header1', '1'];
- const messageList = renderMessages({ messages, narrow });
+ const messageList = renderMessages(messages, narrow);
const messageKeys = messageList.map(x => x.key);
expect(messageKeys).toEqual(expectedComponentKeys);
@@ -62,7 +60,7 @@ describe('renderMessages', () => {
const expectedComponentKeys = ['time123', 'header1', '1', '2', '3'];
- const messageList = renderMessages({ messages, narrow });
+ const messageList = renderMessages(messages, narrow);
const messageKeys = messageList.map(x => x.key);
expect(messageKeys).toEqual(expectedComponentKeys);
@@ -104,7 +102,7 @@ describe('renderMessages', () => {
const expectedComponentKeys = ['time123', 'header1', '1', '2', '3'];
- const messageList = renderMessages({ messages, narrow });
+ const messageList = renderMessages(messages, narrow);
const messageKeys = messageList.map(x => x.key);
expect(messageKeys).toEqual(expectedComponentKeys);
@@ -135,7 +133,7 @@ describe('renderMessages', () => {
const expectedComponentTypes = ['time123', 'header1', '1', '2'];
- const messageList = renderMessages({ messages, narrow });
+ const messageList = renderMessages(messages, narrow);
const messageTypes = messageList.map(x => x.key);
expect(messageTypes).toEqual(expectedComponentTypes);
diff --git a/src/message/messageSelectors.js b/src/message/messageSelectors.js
new file mode 100644
index 00000000000..3d96a27a099
--- /dev/null
+++ b/src/message/messageSelectors.js
@@ -0,0 +1,12 @@
+/* @flow */
+import { createSelector } from 'reselect';
+
+import { getActiveNarrow } from '../baseSelectors';
+import { getShownMessagesInActiveNarrow } from '../chat/chatSelectors';
+import renderMessages from './renderMessages';
+
+export const getRenderedMessages = createSelector(
+ getShownMessagesInActiveNarrow,
+ getActiveNarrow,
+ (messages, narrow) => renderMessages(messages, narrow),
+);
diff --git a/src/message/renderMessages.js b/src/message/renderMessages.js
index bf8ecb5ba0a..8f806c7d0f6 100644
--- a/src/message/renderMessages.js
+++ b/src/message/renderMessages.js
@@ -1,7 +1,7 @@
/* @flow */
import React from 'react';
-import type { Narrow } from '../types';
+import type { Message, Narrow } from '../types';
import {
isTopicNarrow,
isPrivateOrGroupNarrow,
@@ -14,12 +14,7 @@ import TimeRow from '../message/TimeRow';
import { isSameRecipient } from '../utils/message';
import { isSameDay } from '../utils/date';
-type Props = {
- messages: any[],
- narrow: Narrow,
-};
-
-export default ({ messages, narrow }: Props) => {
+export default (messages: Message[], narrow: Narrow) => {
const list: Object[] = [];
let prevItem;
@@ -83,5 +78,6 @@ export default ({ messages, narrow }: Props) => {
prevItem = item;
}
+
return list;
};
diff --git a/src/search/SearchMessagesCard.js b/src/search/SearchMessagesCard.js
index 9451f5f400e..6f914986990 100644
--- a/src/search/SearchMessagesCard.js
+++ b/src/search/SearchMessagesCard.js
@@ -10,6 +10,7 @@ import { BRAND_COLOR } from '../styles';
import { searchNarrow } from '../utils/narrow';
import MessageList from '../message/MessageList';
import { getMessages } from '../api';
+import renderMessages from '../message/renderMessages';
const styles = StyleSheet.create({
empty: {
@@ -27,12 +28,10 @@ const styles = StyleSheet.create({
type Props = {
actions: Actions,
- twentyFourHourTime: boolean,
- subscriptions: any[],
query: string,
auth: Auth,
- flags: Object,
};
+
export default class SearchMessagesCard extends PureComponent {
props: Props;
@@ -70,13 +69,15 @@ export default class SearchMessagesCard extends PureComponent {
render() {
const { isFetching, messages, query } = this.state;
- const { actions, auth, subscriptions, twentyFourHourTime, flags } = this.props;
+ const { actions } = this.props;
const noResults = !!query && !isFetching && !messages.length;
if (noResults) {
return ;
}
+ const renderedMessages = renderMessages(messages, []);
+
return (
{isFetching &&
@@ -84,17 +85,12 @@ export default class SearchMessagesCard extends PureComponent {
diff --git a/src/search/SearchMessagesContainer.js b/src/search/SearchMessagesContainer.js
index e4f36b05526..fb9bdc5998c 100644
--- a/src/search/SearchMessagesContainer.js
+++ b/src/search/SearchMessagesContainer.js
@@ -8,12 +8,6 @@ import SearchMessagesCard from './SearchMessagesCard';
export default connect(
state => ({
auth: getAuth(state),
- isOnline: state.app.isOnline,
- subscriptions: state.subscriptions,
- narrow: state.chat.narrow,
- startReached: state.chat.startReached,
- streamlistOpened: state.nav.opened,
- flags: state.flags,
}),
boundActions,
)(SearchMessagesCard);
diff --git a/src/selectors.js b/src/selectors.js
index 4dc661ad29a..154d22d2391 100644
--- a/src/selectors.js
+++ b/src/selectors.js
@@ -6,6 +6,7 @@ export * from './conversations/conversationsSelectors';
export * from './caughtup/caughtUpSelectors';
export * from './chat/chatSelectors';
export * from './subscriptions/subscriptionSelectors';
+export * from './message/messageSelectors';
export * from './nav/navSelectors';
export * from './nav/navigationSelectors';
export * from './title/titleSelectors';