Skip to content

Commit

Permalink
Refactor UserList and ComposeBox (#1002)
Browse files Browse the repository at this point in the history
  • Loading branch information
borisyankov committed Aug 8, 2017
1 parent 4ef158d commit 47bfb9c
Show file tree
Hide file tree
Showing 11 changed files with 99 additions and 66 deletions.
4 changes: 2 additions & 2 deletions src/chat/Chat.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import MessageList from '../message/MessageList';
// import MessageList from '../message/MessageListFlatList';
import MessageListLoading from '../message/MessageListLoading';
import NoMessages from '../message/NoMessages';
import ComposeBox from '../compose/ComposeBox';
import ComposeBoxContainer from '../compose/ComposeBoxContainer';
// import UnreadNotice from './UnreadNotice';
import NotSubscribed from '../message/NotSubscribed';

Expand Down Expand Up @@ -56,7 +56,7 @@ export default class Chat extends PureComponent {
const { isFetching, messages, narrow, isOnline, isSubscribed } = this.props;
const noMessages = messages.length === 0;
const WrapperView = Platform.OS === 'ios' ? KeyboardAvoidingView : View;
const CheckSub = isSubscribed ? <ComposeBox /> : <NotSubscribed />;
const CheckSub = isSubscribed ? <ComposeBoxContainer /> : <NotSubscribed />;

return (
<WrapperView style={styles.screen} behavior="padding">
Expand Down
4 changes: 2 additions & 2 deletions src/common/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ export { default as OfflineNotice } from './OfflineNotice';
export { default as Popup } from './Popup';
export { default as RawLabel } from './RawLabel';
export { default as Screen } from './Screen';
export { default as SearchEmptyState } from './SearchEmptyState';
export { default as SearchInput } from './SearchInput';
export { default as SlideAnimationView } from './SlideAnimationView';
export { default as TextAvatar } from './TextAvatar';
export { default as Touchable } from './Touchable';
export { default as UnreadCount } from './UnreadCount';
export { default as UserStatusIndicator } from './UserStatusIndicator';
export { default as ZulipButton } from './ZulipButton';
export { default as ZulipStatusBar } from './ZulipStatusBar';
export { default as ZulipSwitch } from './ZulipSwitch';
export { default as SlideAnimationView } from './SlideAnimationView';
export { default as SearchEmptyState } from './SearchEmptyState';
46 changes: 19 additions & 27 deletions src/compose/ComposeBox.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
/* @flow */
import React, { PureComponent } from 'react';
import { StyleSheet, View } from 'react-native';
import { connect } from 'react-redux';

import type { Auth, Narrow, GlobalState, EditMessage, User } from '../types';
import boundActions from '../boundActions';
import type { Auth, Narrow, EditMessage, User } from '../types';
import { Input, MultilineInput } from '../common';
import { isStreamNarrow, isTopicNarrow, isPrivateOrGroupNarrow } from '../utils/narrow';
import { getAuth, getLastTopicInActiveNarrow } from '../selectors';
import ComposeMenu from './ComposeMenu';
import ComposeMenuContainer from './ComposeMenuContainer';
import SubmitButton from './SubmitButton';
import AutoCompleteView from '../autocomplete/AutoCompleteView';
import sendMessage from '../api/sendMessage';
Expand All @@ -34,20 +31,22 @@ const componentStyles = StyleSheet.create({
},
});

class ComposeBox extends PureComponent {
type Props = {
auth: Auth,
narrow: Narrow,
users: User[],
editMessage: EditMessage,
};

export default class ComposeBox extends PureComponent {
topicInput = null;
messageInput = null;

static contextTypes = {
styles: () => null,
};

props: {
auth: Auth,
narrow: Narrow,
users: User[],
editMessage: EditMessage,
};
props: Props;

state: {
optionSelected: number,
Expand Down Expand Up @@ -105,11 +104,15 @@ class ComposeBox extends PureComponent {
this.clearMessageInput();
};

handleAutoComplete = input => this.setState({ message: input });
handleAutoComplete = (input: string) => {
this.setState({ message: input });
};

handleChangeText = input => this.setState({ message: input });
handleChangeText = (input: string) => {
this.setState({ message: input });
};

componentWillReceiveProps(nextProps) {
componentWillReceiveProps(nextProps: Props) {
if (nextProps.editMessage !== this.props.editMessage) {
this.setState({
message: nextProps.editMessage ? nextProps.editMessage.content : '',
Expand All @@ -132,7 +135,7 @@ class ComposeBox extends PureComponent {
<AutoCompleteView text={message} onAutocomplete={this.handleAutoComplete} />
<View style={[styles.composeBox, { height: totalHeight }]}>
<View style={componentStyles.bottom}>
<ComposeMenu />
<ComposeMenuContainer />
</View>
<View style={[componentStyles.composeText]}>
{canSelectTopic &&
Expand Down Expand Up @@ -165,14 +168,3 @@ class ComposeBox extends PureComponent {
);
}
}

export default connect(
(state: GlobalState) => ({
auth: getAuth(state),
narrow: state.chat.narrow,
users: state.users,
lastTopic: getLastTopicInActiveNarrow(state),
editMessage: state.app.editMessage,
}),
boundActions,
)(ComposeBox);
19 changes: 19 additions & 0 deletions src/compose/ComposeBoxContainer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/* @flow */
import { connect } from 'react-redux';

import type { GlobalState } from '../types';
import boundActions from '../boundActions';
import { getAuth, getLastTopicInActiveNarrow } from '../selectors';

import ComposeBox from './ComposeBox';

export default connect(
(state: GlobalState) => ({
auth: getAuth(state),
narrow: state.chat.narrow,
users: state.users,
lastTopic: getLastTopicInActiveNarrow(state),
editMessage: state.app.editMessage,
}),
boundActions,
)(ComposeBox);
28 changes: 12 additions & 16 deletions src/compose/ComposeMenu.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,36 @@
/* @flow */
import React from 'react';
import { StyleSheet, View } from 'react-native';
import { connectActionSheet, ActionSheetProvider } from '@expo/react-native-action-sheet';
import { StyleSheet } from 'react-native';

import { Touchable } from '../common';
import { IconPlus } from '../common/Icons';

const componentStyles = StyleSheet.create({
wrapper: {
height: 44,
},
touchable: {},
button: {
padding: 10,
color: '#999',
},
});

class ComposeMenu extends React.Component {
export default class ComposeMenu extends React.Component {
handlePress = () => {
this.props.showActionSheetWithOptions(
{
options: ['Hide topic edit', 'Create group', 'Upload image', 'Cancel'],
cancelButtonIndex: 3,
},
buttonIndex => {
// Do something here depending on the button index selected
switch (buttonIndex) {
case 1: {
const { actions } = this.props;
actions.navigateToCreateGroup();
break;
}

default:
break;
}
},
);
};
Expand All @@ -38,12 +43,3 @@ class ComposeMenu extends React.Component {
);
}
}

const ConnectedComposeMenu = connectActionSheet(ComposeMenu);

export default () =>
<View style={componentStyles.wrapper}>
<ActionSheetProvider>
<ConnectedComposeMenu />
</ActionSheetProvider>
</View>;
32 changes: 32 additions & 0 deletions src/compose/ComposeMenuContainer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/* @flow */
import React from 'react';
import { StyleSheet, View } from 'react-native';
import { connect } from 'react-redux';
import { connectActionSheet, ActionSheetProvider } from '@expo/react-native-action-sheet';

import { getAuth } from '../selectors';
import boundActions from '../boundActions';
import ComposeMenu from './ComposeMenu';

const ConnectedComposeMenu = connectActionSheet(ComposeMenu);

const componentStyles = StyleSheet.create({
wrapper: {
height: 44,
},
});

export default connect(
state => ({
auth: getAuth(state),
isHydrated: state.app.isHydrated,
needsInitialFetch: state.app.needsInitialFetch,
}),
boundActions,
)(props =>
<View style={componentStyles.wrapper}>
<ActionSheetProvider>
<ConnectedComposeMenu {...props} />
</ActionSheetProvider>
</View>,
);
3 changes: 3 additions & 0 deletions src/nav/navActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,6 @@ export const navigateToLoading = (): Action => NavigationActions.navigate({ rout

export const navigateToSettingsDetail = (setting: string, title: string): Action =>
NavigationActions.navigate({ routeName: 'settings-detail', params: { setting, title } });

export const navigateToCreateGroup = (): Action =>
NavigationActions.navigate({ routeName: 'group' });
1 change: 1 addition & 0 deletions src/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ export type Actions = {
navigateToGroupDetails: (recipients: UserType) => Action,
navigateToAddNewAccount: (realm: string) => Action,
navigateToLightbox: (realm: string) => Action,
navigateToCreateGroup: () => Action,
switchNarrow: (narrow: Narrow) => Action,
doNarrow: (newNarrow: Narrow, anchor: number) => Action,
messageFetchStart: (narrow: Narrow, fetching: Object) => Action,
Expand Down
14 changes: 6 additions & 8 deletions src/users/UserList.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@
import React, { PureComponent } from 'react';
import { StyleSheet, SectionList } from 'react-native';

import { StyleObj, User } from '../types';
import { RawLabel, SearchEmptyState } from '../common';
import UserItem from './UserItem';
import { sortUserList, filterUserList, groupUsersByInitials } from '../selectors';
import { User } from '../types';

const styles = StyleSheet.create({
list: {
flex: 1,
flexDirection: 'column',
},
groupHeader: {
fontWeight: 'bold',
Expand All @@ -21,14 +20,14 @@ const styles = StyleSheet.create({

export default class UserList extends PureComponent {
props: {
style?: StyleObj,
filter: string,
users: User[],
realm: string,
onNarrow: (email: string) => void,
onPress: (email: string) => void,
};

render() {
const { realm, filter, users, onNarrow } = this.props;
const { filter, style, users, onPress } = this.props;
const shownUsers = sortUserList(filterUserList(users, filter));
const groupedUsers = groupUsersByInitials(shownUsers);
const sections = Object.keys(groupedUsers).map(key => ({ key, data: groupedUsers[key] }));
Expand All @@ -40,7 +39,7 @@ export default class UserList extends PureComponent {

return (
<SectionList
style={styles.list}
style={[styles.list, style]}
initialNumToRender={20}
sections={sections}
keyExtractor={item => item.email}
Expand All @@ -50,8 +49,7 @@ export default class UserList extends PureComponent {
fullName={item.fullName}
avatarUrl={item.avatarUrl}
email={item.email}
onPress={onNarrow}
realm={realm}
onPress={onPress}
status={item.status}
/>}
renderSectionHeader={({ section }) =>
Expand Down
11 changes: 2 additions & 9 deletions src/users/UsersCard.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ export default class UsersCard extends PureComponent {
props: {
actions: Actions,
ownEmail: string,
realm: string,
users: User[],
filter: string,
};
Expand All @@ -21,15 +20,9 @@ export default class UsersCard extends PureComponent {
};

render() {
const { ownEmail, realm, users, filter } = this.props;
const { ownEmail, users, filter } = this.props;
return (
<UserList
ownEmail={ownEmail}
users={users}
filter={filter}
realm={realm}
onNarrow={this.handleUserNarrow}
/>
<UserList ownEmail={ownEmail} users={users} filter={filter} onPress={this.handleUserNarrow} />
);
}
}
3 changes: 1 addition & 2 deletions src/users/UsersContainer.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
/* @flow */
import { connect } from 'react-redux';

import { getOwnEmail, getCurrentRealm, getAllActiveUsersWithStatus } from '../selectors';
import { getOwnEmail, getAllActiveUsersWithStatus } from '../selectors';
import boundActions from '../boundActions';
import UsersCard from './UsersCard';

export default connect(
state => ({
ownEmail: getOwnEmail(state),
realm: getCurrentRealm(state),
users: getAllActiveUsersWithStatus(state),
}),
boundActions,
Expand Down

0 comments on commit 47bfb9c

Please sign in to comment.