From ff877644187b9b8c1d8d192026e6c579aed64cc6 Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Thu, 16 Nov 2017 10:33:52 -0200 Subject: [PATCH] Edit action --- app/actions/actionsTypes.js | 8 ++++- app/actions/messages.js | 26 +++++++++++++++ app/containers/MessageBox.js | 57 ++++++++++++++++++++++++++------- app/containers/message/index.js | 25 +++++++++++++-- app/lib/rocketchat.js | 4 +++ app/reducers/messages.js | 18 +++++++++-- app/sagas/messages.js | 23 ++++++++++--- 7 files changed, 139 insertions(+), 22 deletions(-) diff --git a/app/actions/actionsTypes.js b/app/actions/actionsTypes.js index d0a621d6c..22a8428e2 100644 --- a/app/actions/actionsTypes.js +++ b/app/actions/actionsTypes.js @@ -28,7 +28,13 @@ export const FORGOT_PASSWORD = createRequestTypes('FORGOT_PASSWORD', [ ]); export const ROOMS = createRequestTypes('ROOMS'); export const APP = createRequestTypes('APP', ['READY', 'INIT']); -export const MESSAGES = createRequestTypes('MESSAGES'); +export const MESSAGES = createRequestTypes('MESSAGES', [ + ...defaultTypes, + 'EDIT_INIT', + 'EDIT_REQUEST', + 'EDIT_SUCCESS', + 'EDIT_FAILURE' +]); export const CREATE_CHANNEL = createRequestTypes('CREATE_CHANNEL', [ ...defaultTypes, 'REQUEST_USERS', diff --git a/app/actions/messages.js b/app/actions/messages.js index 2f92816ec..ed95e2aef 100644 --- a/app/actions/messages.js +++ b/app/actions/messages.js @@ -19,3 +19,29 @@ export function messagesFailure(err) { err }; } + +export function editInit(message) { + return { + type: types.MESSAGES.EDIT_INIT, + message + }; +} + +export function editRequest(message) { + return { + type: types.MESSAGES.EDIT_REQUEST, + message + }; +} + +export function editSuccess() { + return { + type: types.MESSAGES.EDIT_SUCCESS + }; +} + +export function editFailure() { + return { + type: types.MESSAGES.EDIT_FAILURE + }; +} diff --git a/app/containers/MessageBox.js b/app/containers/MessageBox.js index 7fa265aa6..4242972d8 100644 --- a/app/containers/MessageBox.js +++ b/app/containers/MessageBox.js @@ -3,7 +3,9 @@ import PropTypes from 'prop-types'; import { View, TextInput, StyleSheet, SafeAreaView } from 'react-native'; import Icon from 'react-native-vector-icons/MaterialIcons'; import ImagePicker from 'react-native-image-picker'; +import { connect } from 'react-redux'; import RocketChat from '../lib/rocketchat'; +import { editRequest } from '../actions/messages'; const styles = StyleSheet.create({ textBox: { @@ -19,7 +21,7 @@ const styles = StyleSheet.create({ textBoxInput: { height: 40, alignSelf: 'stretch', - backgroundColor: '#fff', + // backgroundColor: '#fff', flexGrow: 1 }, fileButton: { @@ -29,24 +31,55 @@ const styles = StyleSheet.create({ paddingTop: 10, paddingBottom: 10, fontSize: 20 + }, + editing: { + backgroundColor: '#fff5df' } }); -export default class MessageBox extends React.PureComponent { +@connect(state => ({ + message: state.messages.message, + editing: state.messages.editing +}), dispatch => ({ + editRequest: message => dispatch(editRequest(message)) +})) +export default class MessageBox extends React.Component { static propTypes = { onSubmit: PropTypes.func.isRequired, - rid: PropTypes.string.isRequired + editRequest: PropTypes.func.isRequired, + rid: PropTypes.string.isRequired, + message: PropTypes.object, + editing: PropTypes.bool } - submit(message) { - const text = message; - if (text.trim() === '') { + constructor(props) { + super(props); + this.state = { message: '' }; + } + + componentWillReceiveProps(props) { + if (props.message) { + this.setState({ message: props.message.msg }); + this.component.focus(); + } + } + + submit() { + const { message } = this.state; + const { editing } = this.props; + if (message.trim() === '') { return; } - if (this.component) { - this.component.setNativeProps({ text: '' }); + + // if is editing a message + if (editing) { + const { _id, rid } = this.props.message; + this.props.editRequest({ _id, msg: message, rid }); + } else { + // if is submiting a new message + this.props.onSubmit(message); } - this.props.onSubmit(text); + this.setState({ message: '' }); } addFile = () => { @@ -78,18 +111,20 @@ export default class MessageBox extends React.PureComponent { render() { return ( - + this.component = component} style={styles.textBoxInput} returnKeyType='send' - onSubmitEditing={event => this.submit(event.nativeEvent.text)} + onSubmitEditing={() => this.submit()} blurOnSubmit={false} placeholder='New message' underlineColorAndroid='transparent' defaultValue='' + value={this.state.message} + onChangeText={message => this.setState({ message })} /> diff --git a/app/containers/message/index.js b/app/containers/message/index.js index d6ff7cfaf..4d9ec6146 100644 --- a/app/containers/message/index.js +++ b/app/containers/message/index.js @@ -4,11 +4,13 @@ import { View, StyleSheet, TouchableOpacity, Text, Alert } from 'react-native'; import { emojify } from 'react-emojione'; import Markdown from 'react-native-easy-markdown'; import ActionSheet from 'react-native-actionsheet'; +import { connect } from 'react-redux'; import Card from './Card'; import User from './User'; import Avatar from '../Avatar'; import RocketChat from '../../lib/rocketchat'; +import { editInit } from '../../actions/messages'; const title = 'Message actions'; const options = ['Cancel', 'Reply', 'Edit', 'Permalink', 'Copy', 'Quote', 'Star Message', 'Delete']; @@ -30,14 +32,24 @@ const styles = StyleSheet.create({ textInfo: { fontStyle: 'italic', color: '#a0a0a0' + }, + editing: { + backgroundColor: '#fff5df' } }); -export default class Message extends React.PureComponent { +@connect(state => ({ + message: state.messages.message +}), dispatch => ({ + editInit: message => dispatch(editInit(message)) +})) +export default class Message extends React.Component { static propTypes = { item: PropTypes.object.isRequired, baseUrl: PropTypes.string.isRequired, - Message_TimeFormat: PropTypes.string.isRequired + Message_TimeFormat: PropTypes.string.isRequired, + editInit: PropTypes.func.isRequired, + message: PropTypes.object } constructor(props) { @@ -81,9 +93,16 @@ export default class Message extends React.PureComponent { ); } + handleEdit() { + const { _id, msg, rid } = this.props.item; + this.props.editInit({ _id, msg, rid }); + } + handleActionPress = (actionIndex) => { if (actionIndex === 7) { this.handleDelete(); + } else if (actionIndex === 2) { + this.handleEdit(); } else { console.log(actionIndex, this.props.item); } @@ -113,11 +132,13 @@ export default class Message extends React.PureComponent { } const username = item.alias || item.u.username; + const isEditing = this.props.message._id === item._id; return ( this.showActions()} disabled={this.isDeleted()} + style={isEditing ? styles.editing : null} > RocketChat.editMessage(message); + const get = function* get({ rid }) { const auth = yield select(state => state.login.isAuthenticated); if (!auth) { @@ -17,7 +19,18 @@ const get = function* get({ rid }) { yield put(messagesFailure(err.status)); } }; -const getData = function* getData() { - yield takeLatest(MESSAGES.REQUEST, get); + +const handleEditRequest = function* handleEditRequest({ message }) { + try { + yield call(editMessage, message); + yield put(editSuccess()); + } catch (error) { + yield put(editFailure()); + } }; -export default getData; + +const root = function* root() { + yield takeLatest(MESSAGES.REQUEST, get); + yield takeLatest(MESSAGES.EDIT_REQUEST, handleEditRequest); +}; +export default root;