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 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',

View File

@ -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
};
}

View File

@ -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 (
<View style={styles.textBox}>
<View style={[styles.textBox, (this.props.editing ? styles.editing : null)]}>
<SafeAreaView style={styles.safeAreaView}>
<Icon style={styles.fileButton} name='add-circle-outline' onPress={this.addFile} />
<TextInput
ref={component => 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 })}
/>
</SafeAreaView>
</View>

View File

@ -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 (
<TouchableOpacity
onLongPress={() => this.showActions()}
disabled={this.isDeleted()}
style={isEditing ? styles.editing : null}
>
<View style={[styles.message, extraStyle]}>
<Avatar

View File

@ -457,6 +457,10 @@ const RocketChat = {
},
deleteMessage(message) {
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 = {
isFetching: false,
failure: false
failure: false,
message: {},
editing: false
};
export default function messages(state = initialState, action) {
@ -24,8 +26,18 @@ export default function messages(state = initialState, action) {
failure: true,
errorMessage: action.err
};
// case types.LOGOUT:
// return initialState;
case types.MESSAGES.EDIT_INIT:
return {
...state,
message: action.message,
editing: true
};
case types.MESSAGES.EDIT_SUCCESS:
return {
...state,
message: {},
editing: false
};
default:
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 { messagesSuccess, messagesFailure } from '../actions/messages';
import { messagesSuccess, messagesFailure, editSuccess, editFailure } from '../actions/messages';
import RocketChat from '../lib/rocketchat';
const editMessage = message => 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;