Better touch handling on rooms list (#462)

* Use react-native-gesture-handler at RoomItem

* Fixed info message author

* Edit message render improvement

* Fix ws to http replace
This commit is contained in:
Diego Mello 2018-09-26 16:38:06 -03:00 committed by GitHub
parent c58df3b4ab
commit d6162d9fc8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 48 additions and 4048 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -41,9 +41,9 @@ const SYSTEM_MESSAGES = [
]; ];
const getInfoMessage = ({ const getInfoMessage = ({
type, role, msg, user type, role, msg, author
}) => { }) => {
const { username } = user; const { username } = author;
if (type === 'rm') { if (type === 'rm') {
return I18n.t('Message_removed'); return I18n.t('Message_removed');
} else if (type === 'uj') { } else if (type === 'uj') {

View File

@ -14,10 +14,9 @@ import {
@connect(state => ({ @connect(state => ({
baseUrl: state.settings.Site_Url || state.server ? state.server.server : '', baseUrl: state.settings.Site_Url || state.server ? state.server.server : '',
customEmojis: state.customEmojis, customEmojis: state.customEmojis,
editing: state.messages.editing,
Message_GroupingPeriod: state.settings.Message_GroupingPeriod, Message_GroupingPeriod: state.settings.Message_GroupingPeriod,
Message_TimeFormat: state.settings.Message_TimeFormat, Message_TimeFormat: state.settings.Message_TimeFormat,
message: state.messages.message, editingMessage: state.messages.message,
useRealName: state.settings.UI_Use_Real_Name useRealName: state.settings.UI_Use_Real_Name
}), dispatch => ({ }), dispatch => ({
errorActionsShow: actionMessage => dispatch(errorActionsShowAction(actionMessage)), errorActionsShow: actionMessage => dispatch(errorActionsShowAction(actionMessage)),
@ -43,10 +42,9 @@ export default class MessageContainer extends React.Component {
// redux // redux
baseUrl: PropTypes.string, baseUrl: PropTypes.string,
customEmojis: PropTypes.object, customEmojis: PropTypes.object,
editing: PropTypes.bool,
Message_GroupingPeriod: PropTypes.number, Message_GroupingPeriod: PropTypes.number,
Message_TimeFormat: PropTypes.string, Message_TimeFormat: PropTypes.string,
message: PropTypes.object, editingMessage: PropTypes.object,
useRealName: PropTypes.bool, useRealName: PropTypes.bool,
// methods - props // methods - props
onLongPress: PropTypes.func, onLongPress: PropTypes.func,
@ -73,7 +71,7 @@ export default class MessageContainer extends React.Component {
shouldComponentUpdate(nextProps, nextState) { shouldComponentUpdate(nextProps, nextState) {
const { reactionsModal } = this.state; const { reactionsModal } = this.state;
const { const {
status, reactions, broadcast, editing, _updatedAt status, reactions, broadcast, _updatedAt, editingMessage, item
} = this.props; } = this.props;
if (reactionsModal !== nextState.reactionsModal) { if (reactionsModal !== nextState.reactionsModal) {
@ -92,8 +90,12 @@ export default class MessageContainer extends React.Component {
if (broadcast !== nextProps.broadcast) { if (broadcast !== nextProps.broadcast) {
return true; return true;
} }
if (editing !== nextProps.editing) { if (!equal(editingMessage, nextProps.editingMessage)) {
if (nextProps.editingMessage && nextProps.editingMessage._id === item._id) {
return true; return true;
} else if (!nextProps.editingMessage._id !== item._id && editingMessage._id === item._id) {
return true;
}
} }
return _updatedAt.toGMTString() !== nextProps._updatedAt.toGMTString(); return _updatedAt.toGMTString() !== nextProps._updatedAt.toGMTString();
} }
@ -163,12 +165,12 @@ export default class MessageContainer extends React.Component {
render() { render() {
const { reactionsModal } = this.state; const { reactionsModal } = this.state;
const { const {
item, message, editing, user, style, archived, baseUrl, customEmojis, useRealName, broadcast item, editingMessage, user, style, archived, baseUrl, customEmojis, useRealName, broadcast
} = this.props; } = this.props;
const { const {
msg, ts, attachments, urls, reactions, t, status, avatar, u, alias, editedBy, role msg, ts, attachments, urls, reactions, t, status, avatar, u, alias, editedBy, role
} = item; } = item;
const isEditing = message._id === item._id && editing; const isEditing = editingMessage._id === item._id;
return ( return (
<Message <Message
msg={msg} msg={msg}

View File

@ -13,7 +13,7 @@ const restTypes = {
async function canOpenRoomREST({ type, rid }) { async function canOpenRoomREST({ type, rid }) {
try { try {
const { token, id } = this.ddp._login; const { token, id } = this.ddp._login;
const server = this.ddp.url.replace('ws', 'http'); const server = this.ddp.url.replace(/^ws/, 'http');
await post({ token, id, server }, `${ restTypes[type] }.open`, { roomId: rid }); await post({ token, id, server }, `${ restTypes[type] }.open`, { roomId: rid });
return true; return true;
} catch (error) { } catch (error) {

View File

@ -17,7 +17,7 @@ const getRoomRest = async function() {
const { ddp } = this; const { ddp } = this;
const updatedSince = lastMessage(); const updatedSince = lastMessage();
const { token, id } = ddp._login; const { token, id } = ddp._login;
const server = this.ddp.url.replace('ws', 'http'); const server = this.ddp.url.replace(/^ws/, 'http');
const [subscriptions, rooms] = await Promise.all([get({ token, id, server }, 'subscriptions.get', { updatedSince }), get({ token, id, server }, 'rooms.get', { updatedSince })]); const [subscriptions, rooms] = await Promise.all([get({ token, id, server }, 'subscriptions.get', { updatedSince }), get({ token, id, server }, 'rooms.get', { updatedSince })]);
return mergeSubscriptionsRooms(subscriptions, rooms); return mergeSubscriptionsRooms(subscriptions, rooms);
}; };

View File

@ -12,7 +12,7 @@ const types = {
async function loadMessagesForRoomRest({ rid: roomId, latest, t }) { async function loadMessagesForRoomRest({ rid: roomId, latest, t }) {
const { token, id } = this.ddp._login; const { token, id } = this.ddp._login;
const server = this.ddp.url.replace('ws', 'http'); const server = this.ddp.url.replace(/^ws/, 'http');
const data = await get({ token, id, server }, `${ types[t] }.history`, { roomId, latest }); const data = await get({ token, id, server }, `${ types[t] }.history`, { roomId, latest });
if (!data || data.status === 'error') { if (!data || data.status === 'error') {
return []; return [];

View File

@ -7,7 +7,7 @@ import log from '../../utils/log';
async function loadMissedMessagesRest({ rid: roomId, lastOpen: lastUpdate }) { async function loadMissedMessagesRest({ rid: roomId, lastOpen: lastUpdate }) {
const { token, id } = this.ddp._login; const { token, id } = this.ddp._login;
const server = this.ddp.url.replace('ws', 'http'); const server = this.ddp.url.replace(/^ws/, 'http');
const { result } = await get({ token, id, server }, 'chat.syncMessages', { roomId, lastUpdate }); const { result } = await get({ token, id, server }, 'chat.syncMessages', { roomId, lastUpdate });
// TODO: api fix // TODO: api fix
if (!result) { if (!result) {

View File

@ -4,7 +4,7 @@ import log from '../../utils/log';
const readMessagesREST = function readMessagesREST(rid) { const readMessagesREST = function readMessagesREST(rid) {
const { token, id } = this.ddp._login; const { token, id } = this.ddp._login;
const server = this.ddp.url.replace('ws', 'http'); const server = this.ddp.url.replace(/^ws/, 'http');
return post({ token, id, server }, 'subscriptions.read', { rid }); return post({ token, id, server }, 'subscriptions.read', { rid });
}; };

View File

@ -33,7 +33,7 @@ export const getMessage = (rid, msg = {}) => {
function sendMessageByRest(message) { function sendMessageByRest(message) {
const { token, id } = this.ddp._login; const { token, id } = this.ddp._login;
const server = this.ddp.url.replace('ws', 'http'); const server = this.ddp.url.replace(/^ws/, 'http');
const { _id, rid, msg } = message; const { _id, rid, msg } = message;
return post({ token, id, server }, 'chat.sendMessage', { message: { _id, rid, msg } }); return post({ token, id, server }, 'chat.sendMessage', { message: { _id, rid, msg } });
} }

View File

@ -6,6 +6,7 @@ import {
} from 'react-native'; } from 'react-native';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { emojify } from 'react-emojione'; import { emojify } from 'react-emojione';
import { RectButton } from 'react-native-gesture-handler';
import Avatar from '../containers/Avatar'; import Avatar from '../containers/Avatar';
import Status from '../containers/status'; import Status from '../containers/status';
@ -142,7 +143,6 @@ export default class RoomItem extends React.Component {
userMentions: PropTypes.number, userMentions: PropTypes.number,
id: PropTypes.string, id: PropTypes.string,
onPress: PropTypes.func, onPress: PropTypes.func,
onLongPress: PropTypes.func,
username: PropTypes.string, username: PropTypes.string,
avatarSize: PropTypes.number, avatarSize: PropTypes.number,
testID: PropTypes.string, testID: PropTypes.string,
@ -229,7 +229,7 @@ export default class RoomItem extends React.Component {
render() { render() {
const { const {
favorite, unread, userMentions, name, _updatedAt, alert, testID, height, onPress, onLongPress favorite, unread, userMentions, name, _updatedAt, alert, testID, height, onPress
} = this.props; } = this.props;
const date = this.formatDate(_updatedAt); const date = this.formatDate(_updatedAt);
@ -250,16 +250,16 @@ export default class RoomItem extends React.Component {
} }
return ( return (
<Touch <RectButton
onPress={onPress} onPress={onPress}
onLongPress={onLongPress} activeOpacity={0.8}
underlayColor='#FFFFFF' underlayColor='#e1e5e8'
activeOpacity={0.5}
accessibilityLabel={accessibilityLabel}
accessibilityTraits='selected'
testID={testID} testID={testID}
> >
<View style={[styles.container, favorite && styles.favorite, height && { height }]}> <View
style={[styles.container, favorite && styles.favorite, height && { height }]}
accessibilityLabel={accessibilityLabel}
>
{this.avatar} {this.avatar}
<View style={styles.centerContainer}> <View style={styles.centerContainer}>
<View style={styles.titleContainer}> <View style={styles.titleContainer}>
@ -276,7 +276,7 @@ export default class RoomItem extends React.Component {
</View> </View>
{this.renderDisclosureIndicator()} {this.renderDisclosureIndicator()}
</View> </View>
</Touch> </RectButton>
); );
} }
} }

View File

@ -7,6 +7,7 @@ import Icon from 'react-native-vector-icons/Ionicons';
import MaterialIcon from 'react-native-vector-icons/MaterialIcons'; import MaterialIcon from 'react-native-vector-icons/MaterialIcons';
import { connect, Provider } from 'react-redux'; import { connect, Provider } from 'react-redux';
import { Navigation } from 'react-native-navigation'; import { Navigation } from 'react-native-navigation';
import { gestureHandlerRootHOC } from 'react-native-gesture-handler';
import { leaveRoom as leaveRoomAction } from '../../actions/room'; import { leaveRoom as leaveRoomAction } from '../../actions/room';
import LoggedView from '../View'; import LoggedView from '../View';
@ -74,7 +75,7 @@ export default class RoomActionsView extends LoggedView {
if (item.route) { if (item.route) {
if (modules[item.route] == null) { if (modules[item.route] == null) {
modules[item.route] = item.require(); modules[item.route] = item.require();
Navigation.registerComponent(item.route, () => modules[item.route], store, Provider); Navigation.registerComponent(item.route, () => gestureHandlerRootHOC(modules[item.route]), store, Provider);
} }
navigator.push({ navigator.push({
screen: item.route, screen: item.route,