diff --git a/src/compose/ComposeBox.js b/src/compose/ComposeBox.js index 915094d1225..e22bb9d22a1 100644 --- a/src/compose/ComposeBox.js +++ b/src/compose/ComposeBox.js @@ -1,11 +1,15 @@ /* @flow */ import React from 'react'; import { View } from 'react-native'; +import { connect } from 'react-redux'; +import { getAuth } from '../account/accountSelectors'; import styles from '../styles'; -// import ComposeOptions from './ComposeOptions'; import ComposeText from './ComposeText'; import CameraRollView from './CameraRollView'; +import ModeView from './ModeView'; +import { getLastTopicInActiveNarrow } from '../chat/chatSelectors'; + type Props = { onSend: (content: string) => void, @@ -19,8 +23,7 @@ const composeComponents = [ View, ]; -export default class ComposeBox extends React.Component { - +class ComposeBox extends React.Component { props: Props; state: { @@ -29,23 +32,48 @@ export default class ComposeBox extends React.Component { constructor(props: Props) { super(props); - this.state = { - optionSelected: 0, - }; + this.state = { optionSelected: 0, operator: null }; } + setOperator = (operator: string) => this.setState({ operator }); + handleOptionSelected = (optionSelected: number) => this.setState({ optionSelected }); render() { - const { optionSelected } = this.state; + const { optionSelected, operator } = this.state; + const { auth, narrow, users, lastTopic } = this.props; const ActiveComposeComponent = composeComponents[optionSelected]; return ( - - {/* */} + + + + + ); } } + +const mapStateToProps = (state) => ({ + auth: getAuth(state), + narrow: state.chat.narrow, + users: state.users, + lastTopic: getLastTopicInActiveNarrow(state), +}); + +export default connect(mapStateToProps)(ComposeBox); diff --git a/src/compose/ComposeText.js b/src/compose/ComposeText.js index e263fe43bf7..7004d48645a 100644 --- a/src/compose/ComposeText.js +++ b/src/compose/ComposeText.js @@ -1,15 +1,12 @@ /* @flow */ import React from 'react'; import { StyleSheet, View, ScrollView, TextInput } from 'react-native'; -import { connect } from 'react-redux'; import styles from '../styles'; import { MatchResult } from '../types'; import { Input } from '../common'; import { isStreamNarrow, isTopicNarrow, isPrivateOrGroupNarrow } from '../utils/narrow'; import { registerUserInputActivity } from '../utils/activity'; -import { getAuth } from '../account/accountSelectors'; -import { getLastTopicInActiveNarrow } from '../chat/chatSelectors'; import sendMessage from '../api/sendMessage'; import SendButton from './SendButton'; import getAutocompletedText from '../autocomplete/getAutocompletedText'; @@ -23,7 +20,7 @@ const MAX_HEIGHT = 200; const componentStyles = StyleSheet.create({ wrapper: { flexDirection: 'row', - alignItems: 'center', + alignItems: 'center' }, messageBox: { flex: 1, @@ -35,7 +32,7 @@ type Props = { narrow: Object, }; -class ComposeText extends React.Component { +export default class ComposeText extends React.Component { props: Props; textInput: TextInput; @@ -58,17 +55,23 @@ class ComposeText extends React.Component { } handleSend = () => { - const { auth, narrow } = this.props; + const { auth, narrow, operator } = this.props; const { text } = this.state; if (isPrivateOrGroupNarrow(narrow)) { sendMessage(auth, 'private', narrow[0].operand, '', text); - } else if (isStreamNarrow(narrow)) { - sendMessage(auth, 'stream', narrow[0].operand, '(no topic)', text); - } else if (isTopicNarrow(narrow)) { - sendMessage(auth, 'stream', narrow[0].operand, narrow[1].operand, text); + } else if (isTopicNarrow(narrow) || isStreamNarrow(narrow)) { + if (operator !== null) { + sendMessage(auth, 'stream', narrow[0].operand, + (operator === '') ? '(no topic)' : operator, text); + } else if (isTopicNarrow(narrow)) { + sendMessage(auth, 'stream', narrow[0].operand, narrow[1].operand, text); + } else if (isStreamNarrow(narrow)) { + sendMessage(auth, 'stream', narrow[0].operand, '(no topic)', text); + } } + this.clearInput(); } @@ -100,7 +103,6 @@ class ComposeText extends React.Component { const height = Math.min(Math.max(MIN_HEIGHT, contentHeight), MAX_HEIGHT); const lastword: MatchResult = text.match(/\b(\w+)$/); const lastWordPrefix = lastword && lastword.index && text[lastword.index - 1]; - return ( {lastWordPrefix === ':' && lastword && @@ -131,11 +133,3 @@ class ComposeText extends React.Component { ); } } - -const mapStateToProps = (state) => ({ - auth: getAuth(state), - narrow: state.chat.narrow, - lastTopic: getLastTopicInActiveNarrow(state), -}); - -export default connect(mapStateToProps)(ComposeText); diff --git a/src/compose/ModeIcon.js b/src/compose/ModeIcon.js new file mode 100644 index 00000000000..f451ce9fe37 --- /dev/null +++ b/src/compose/ModeIcon.js @@ -0,0 +1,14 @@ +import React from 'react'; +import ComposeIcon from './ComposeIcon'; + +export default (props) => { + switch (props.modeSelected) { + case 0: + return (); + case 1: + return (); + default: + return (); + + } +}; diff --git a/src/compose/ModeView.js b/src/compose/ModeView.js new file mode 100644 index 00000000000..016239234ab --- /dev/null +++ b/src/compose/ModeView.js @@ -0,0 +1,71 @@ +import React from 'react'; +import { View, StyleSheet } from 'react-native'; + +import ComposeOptions from './ComposeOptions'; +import ModeIcon from './ModeIcon'; +import StreamBox from './ModeViews/StreamBox'; +import { isTopicNarrow, isStreamNarrow } from '../utils/narrow'; + +const inlineStyles = StyleSheet.create({ + wrapper: { + flexDirection: 'row', + }, + divider: { + width: 2, + backgroundColor: '#ecf0f1', + margin: 4 + }, +}); + +export default class ModeView extends React.Component { + constructor() { + super(); + this.state = { + modeSelected: 0, + }; + } + + handleModeChanged = () => { + const { setOperator, narrow, lastTopic } = this.props; + if (this.state.modeSelected === 0 && (isTopicNarrow(narrow) || isStreamNarrow(narrow))) { + if (narrow.length === 1) { + setOperator(lastTopic); + } else { + setOperator(narrow[1].operand); + } + } else { + setOperator(null); + } + this.setState({ + modeSelected: (this.state.modeSelected === 1) ? 0 : this.state.modeSelected + 1 + }); + }; + + render() { + const { modeSelected } = this.state; + const { setOperator, operator, optionSelected, + handleOptionSelected, narrow, lastTopic } = this.props; + + return ( + + {(isTopicNarrow(narrow) || isStreamNarrow(narrow)) && + + + + + } + {modeSelected === 0 && + + } + {modeSelected === 1 && + + } + + ); + } +} diff --git a/src/compose/ModeViews/StreamBox.js b/src/compose/ModeViews/StreamBox.js new file mode 100644 index 00000000000..5a3553f3610 --- /dev/null +++ b/src/compose/ModeViews/StreamBox.js @@ -0,0 +1,46 @@ +import React, { Component } from 'react'; +import { View, TextInput, StyleSheet } from 'react-native'; + +import { isTopicNarrow } from '../../utils/narrow'; + +const styles = StyleSheet.create({ + streamInputWrapper: { + flexDirection: 'row', alignItems: 'center', flex: 1 + }, + topicInput: { + flex: 0.8, + margin: 2 + } +}); + +export default class StreamBox extends Component { + componentWillReceiveProps(nextProps) { + if (this.props.narrow !== nextProps.narrow) { + if (nextProps.narrow[0].operator !== 'pm-with') { + const { setOperator } = this.props; + if (isTopicNarrow(nextProps.narrow)) { + setOperator(nextProps.narrow[1].operand); + } else { + setOperator(nextProps.lastTopic); + } + } + } + } + + render() { + const { operator, setOperator } = this.props; + return ( + + { this.operandInput = component; }} + style={styles.topicInput} + placeholder={'Topic'} + onChange={(event) => setOperator( + event.nativeEvent.text + )} + value={operator} + /> + + ); + } +} diff --git a/src/i18n/translations/messages_en.json b/src/i18n/translations/messages_en.json index e3b0ecaaffa..0bab50a2928 100644 --- a/src/i18n/translations/messages_en.json +++ b/src/i18n/translations/messages_en.json @@ -47,5 +47,7 @@ "No Internet connection": "No Internet connection", "Settings": "Settings", "Night mode": "Night mode", - "Language": "Language" + "Language": "Language", + "Topic": "Topic", + "Type a message here": "Type a message here" } diff --git a/src/styles/theme.js b/src/styles/theme.js index 9c10a49966f..91e27b98275 100644 --- a/src/styles/theme.js +++ b/src/styles/theme.js @@ -137,4 +137,11 @@ export default ({ color, backgroundColor, borderColor }) => ({ fontSize: 16, lineHeight: 16, }, + composeInput: { + padding: 5, + fontSize: 14, + borderWidth: 0.5, + height: CONTROL_SIZE * 3 / 4, + borderColor: BORDER_COLOR, + }, });