Edit action

This commit is contained in:
Diego Mello 2017-11-16 10:33:52 -02:00
parent c0407c702b
commit ff87764418
7 changed files with 139 additions and 22 deletions

View File

@ -28,7 +28,13 @@ export const FORGOT_PASSWORD = createRequestTypes('FORGOT_PASSWORD', [
]); ]);
export const ROOMS = createRequestTypes('ROOMS'); export const ROOMS = createRequestTypes('ROOMS');
export const APP = createRequestTypes('APP', ['READY', 'INIT']); 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', [ export const CREATE_CHANNEL = createRequestTypes('CREATE_CHANNEL', [
...defaultTypes, ...defaultTypes,
'REQUEST_USERS', 'REQUEST_USERS',

View File

@ -19,3 +19,29 @@ export function messagesFailure(err) {
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
};
}

View File

@ -3,7 +3,9 @@ import PropTypes from 'prop-types';
import { View, TextInput, StyleSheet, SafeAreaView } from 'react-native'; import { View, TextInput, StyleSheet, SafeAreaView } from 'react-native';
import Icon from 'react-native-vector-icons/MaterialIcons'; import Icon from 'react-native-vector-icons/MaterialIcons';
import ImagePicker from 'react-native-image-picker'; import ImagePicker from 'react-native-image-picker';
import { connect } from 'react-redux';
import RocketChat from '../lib/rocketchat'; import RocketChat from '../lib/rocketchat';
import { editRequest } from '../actions/messages';
const styles = StyleSheet.create({ const styles = StyleSheet.create({
textBox: { textBox: {
@ -19,7 +21,7 @@ const styles = StyleSheet.create({
textBoxInput: { textBoxInput: {
height: 40, height: 40,
alignSelf: 'stretch', alignSelf: 'stretch',
backgroundColor: '#fff', // backgroundColor: '#fff',
flexGrow: 1 flexGrow: 1
}, },
fileButton: { fileButton: {
@ -29,24 +31,55 @@ const styles = StyleSheet.create({
paddingTop: 10, paddingTop: 10,
paddingBottom: 10, paddingBottom: 10,
fontSize: 20 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 = { static propTypes = {
onSubmit: PropTypes.func.isRequired, onSubmit: PropTypes.func.isRequired,
rid: PropTypes.string.isRequired editRequest: PropTypes.func.isRequired,
rid: PropTypes.string.isRequired,
message: PropTypes.object,
editing: PropTypes.bool
} }
submit(message) { constructor(props) {
const text = message; super(props);
if (text.trim() === '') { 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; 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 = () => { addFile = () => {
@ -78,18 +111,20 @@ export default class MessageBox extends React.PureComponent {
render() { render() {
return ( return (
<View style={styles.textBox}> <View style={[styles.textBox, (this.props.editing ? styles.editing : null)]}>
<SafeAreaView style={styles.safeAreaView}> <SafeAreaView style={styles.safeAreaView}>
<Icon style={styles.fileButton} name='add-circle-outline' onPress={this.addFile} /> <Icon style={styles.fileButton} name='add-circle-outline' onPress={this.addFile} />
<TextInput <TextInput
ref={component => this.component = component} ref={component => this.component = component}
style={styles.textBoxInput} style={styles.textBoxInput}
returnKeyType='send' returnKeyType='send'
onSubmitEditing={event => this.submit(event.nativeEvent.text)} onSubmitEditing={() => this.submit()}
blurOnSubmit={false} blurOnSubmit={false}
placeholder='New message' placeholder='New message'
underlineColorAndroid='transparent' underlineColorAndroid='transparent'
defaultValue='' defaultValue=''
value={this.state.message}
onChangeText={message => this.setState({ message })}
/> />
</SafeAreaView> </SafeAreaView>
</View> </View>

View File

@ -4,11 +4,13 @@ import { View, StyleSheet, TouchableOpacity, Text, Alert } from 'react-native';
import { emojify } from 'react-emojione'; import { emojify } from 'react-emojione';
import Markdown from 'react-native-easy-markdown'; import Markdown from 'react-native-easy-markdown';
import ActionSheet from 'react-native-actionsheet'; import ActionSheet from 'react-native-actionsheet';
import { connect } from 'react-redux';
import Card from './Card'; import Card from './Card';
import User from './User'; import User from './User';
import Avatar from '../Avatar'; import Avatar from '../Avatar';
import RocketChat from '../../lib/rocketchat'; import RocketChat from '../../lib/rocketchat';
import { editInit } from '../../actions/messages';
const title = 'Message actions'; const title = 'Message actions';
const options = ['Cancel', 'Reply', 'Edit', 'Permalink', 'Copy', 'Quote', 'Star Message', 'Delete']; const options = ['Cancel', 'Reply', 'Edit', 'Permalink', 'Copy', 'Quote', 'Star Message', 'Delete'];
@ -30,14 +32,24 @@ const styles = StyleSheet.create({
textInfo: { textInfo: {
fontStyle: 'italic', fontStyle: 'italic',
color: '#a0a0a0' 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 = { static propTypes = {
item: PropTypes.object.isRequired, item: PropTypes.object.isRequired,
baseUrl: PropTypes.string.isRequired, baseUrl: PropTypes.string.isRequired,
Message_TimeFormat: PropTypes.string.isRequired Message_TimeFormat: PropTypes.string.isRequired,
editInit: PropTypes.func.isRequired,
message: PropTypes.object
} }
constructor(props) { 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) => { handleActionPress = (actionIndex) => {
if (actionIndex === 7) { if (actionIndex === 7) {
this.handleDelete(); this.handleDelete();
} else if (actionIndex === 2) {
this.handleEdit();
} else { } else {
console.log(actionIndex, this.props.item); 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 username = item.alias || item.u.username;
const isEditing = this.props.message._id === item._id;
return ( return (
<TouchableOpacity <TouchableOpacity
onLongPress={() => this.showActions()} onLongPress={() => this.showActions()}
disabled={this.isDeleted()} disabled={this.isDeleted()}
style={isEditing ? styles.editing : null}
> >
<View style={[styles.message, extraStyle]}> <View style={[styles.message, extraStyle]}>
<Avatar <Avatar

View File

@ -457,6 +457,10 @@ const RocketChat = {
}, },
deleteMessage(message) { deleteMessage(message) {
return call('deleteMessage', { _id: message._id }); return call('deleteMessage', { _id: message._id });
},
editMessage(message) {
const { _id, msg, rid } = message;
return call('updateMessage', { _id, msg, rid });
} }
}; };

View File

@ -2,7 +2,9 @@ import * as types from '../actions/actionsTypes';
const initialState = { const initialState = {
isFetching: false, isFetching: false,
failure: false failure: false,
message: {},
editing: false
}; };
export default function messages(state = initialState, action) { export default function messages(state = initialState, action) {
@ -24,8 +26,18 @@ export default function messages(state = initialState, action) {
failure: true, failure: true,
errorMessage: action.err errorMessage: action.err
}; };
// case types.LOGOUT: case types.MESSAGES.EDIT_INIT:
// return initialState; return {
...state,
message: action.message,
editing: true
};
case types.MESSAGES.EDIT_SUCCESS:
return {
...state,
message: {},
editing: false
};
default: default:
return state; return state;
} }

View File

@ -1,8 +1,10 @@
import { takeLatest, select, take, put } from 'redux-saga/effects'; import { takeLatest, select, take, put, call } from 'redux-saga/effects';
import { MESSAGES, LOGIN } from '../actions/actionsTypes'; import { MESSAGES, LOGIN } from '../actions/actionsTypes';
import { messagesSuccess, messagesFailure } from '../actions/messages'; import { messagesSuccess, messagesFailure, editSuccess, editFailure } from '../actions/messages';
import RocketChat from '../lib/rocketchat'; import RocketChat from '../lib/rocketchat';
const editMessage = message => RocketChat.editMessage(message);
const get = function* get({ rid }) { const get = function* get({ rid }) {
const auth = yield select(state => state.login.isAuthenticated); const auth = yield select(state => state.login.isAuthenticated);
if (!auth) { if (!auth) {
@ -17,7 +19,18 @@ const get = function* get({ rid }) {
yield put(messagesFailure(err.status)); 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;