Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 49 additions & 51 deletions app/presentation/RoomItem/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import React from 'react';
import moment from 'moment';
import PropTypes from 'prop-types';
import {
View, Text, Dimensions, Animated
} from 'react-native';
import { View, Text, Animated } from 'react-native';
import { connect } from 'react-redux';
import { RectButton, PanGestureHandler, State } from 'react-native-gesture-handler';

Expand All @@ -18,9 +16,8 @@ import { CustomIcon } from '../../lib/Icons';
export { ROW_HEIGHT };

const OPTION_WIDTH = 80;
const SMALL_SWIPE = 80;
const ACTION_OFFSET = 220;
const attrs = ['name', 'unread', 'userMentions', 'showLastMessage', 'alert', 'type'];
const SMALL_SWIPE = 40;
const attrs = ['name', 'unread', 'userMentions', 'showLastMessage', 'alert', 'type', 'width'];
@connect(state => ({
userId: state.login.user && state.login.user.id,
username: state.login.user && state.login.user.username,
Expand All @@ -45,6 +42,7 @@ export default class RoomItem extends React.Component {
token: PropTypes.string,
avatarSize: PropTypes.number,
testID: PropTypes.string,
width: PropTypes.number,
height: PropTypes.number,
favorite: PropTypes.bool,
isRead: PropTypes.bool,
Expand All @@ -71,9 +69,7 @@ export default class RoomItem extends React.Component {
this.state = {
dragX,
rowOffSet,
rowState: 0, // 0: closed, 1: right opened, -1: left opened
leftWidth: undefined,
rightOffset: undefined
rowState: 0 // 0: closed, 1: right opened, -1: left opened
};
this._onGestureEvent = Animated.event(
[{ nativeEvent: { translationX: dragX } }]
Expand Down Expand Up @@ -104,43 +100,30 @@ export default class RoomItem extends React.Component {
this.rowTranslation.removeAllListeners();
}

close = () => {
this.swipeableRow.close();
};

_onHandlerStateChange = ({ nativeEvent }) => {
if (nativeEvent.oldState === State.ACTIVE) {
this._handleRelease(nativeEvent);
}
};

_currentOffset = () => {
const { leftWidth = 0, rowState } = this.state;
const { rightOffset } = this.state;
if (rowState === 1) {
return leftWidth;
} else if (rowState === -1) {
return rightOffset;
}
return 0;
};

_handleRelease = (nativeEvent) => {
const { translationX } = nativeEvent;
const { rowState } = this.state;
const { width } = this.props;
const halfScreen = width / 2;
let toValue = 0;
if (rowState === 0) { // if no option is opened
if (translationX > 0 && translationX < ACTION_OFFSET) {
if (translationX > 0 && translationX < halfScreen) {
toValue = OPTION_WIDTH; // open left option if he swipe right but not enough to trigger action
this.setState({ rowState: -1 });
} else if (translationX > ACTION_OFFSET) {
} else if (translationX >= halfScreen) {
toValue = 0;
this.toggleRead();
} else if (translationX < 0 && translationX > -ACTION_OFFSET) {
} else if (translationX < 0 && translationX > -halfScreen) {
toValue = -2 * OPTION_WIDTH; // open right option if he swipe left
this.setState({ rowState: 1 });
} else if (translationX < -ACTION_OFFSET) {
toValue = 0;
} else if (translationX <= -halfScreen) {
toValue = -width;
this.hideChannel();
} else {
toValue = 0;
Expand All @@ -151,7 +134,7 @@ export default class RoomItem extends React.Component {
if (this._value < SMALL_SWIPE) {
toValue = 0;
this.setState({ rowState: 0 });
} else if (this._value > ACTION_OFFSET) {
} else if (this._value > halfScreen) {
toValue = 0;
this.setState({ rowState: 0 });
this.toggleRead();
Expand All @@ -164,7 +147,7 @@ export default class RoomItem extends React.Component {
if (this._value > -2 * SMALL_SWIPE) {
toValue = 0;
this.setState({ rowState: 0 });
} else if (this._value < -ACTION_OFFSET) {
} else if (this._value < -halfScreen) {
toValue = 0;
this.setState({ rowState: 0 });
this.hideChannel();
Expand All @@ -181,7 +164,7 @@ export default class RoomItem extends React.Component {
dragX.setValue(0);
Animated.spring(rowOffSet, {
toValue,
bounciness: 5
bounciness: 0
}).start();
}

Expand All @@ -191,6 +174,7 @@ export default class RoomItem extends React.Component {
}

close = () => {
this.setState({ rowState: 0 });
this._animateRow(0);
}

Expand Down Expand Up @@ -221,16 +205,28 @@ export default class RoomItem extends React.Component {
}
}

onPress = () => {
const { rowState } = this.state;
if (rowState !== 0) {
this.close();
return;
}
const { onPress } = this.props;
if (onPress) {
onPress();
}
}

renderLeftActions = () => {
const { isRead } = this.props;
const { width } = Dimensions.get('window');
const { isRead, width } = this.props;
const halfWidth = width / 2;
const trans = this.rowTranslation.interpolate({
inputRange: [0, OPTION_WIDTH],
outputRange: [-width, -width + OPTION_WIDTH]
});

const iconTrans = this.rowTranslation.interpolate({
inputRange: [0, OPTION_WIDTH, ACTION_OFFSET - 20, ACTION_OFFSET, width],
inputRange: [0, OPTION_WIDTH, halfWidth - 1, halfWidth, width],
outputRange: [0, 0, -(OPTION_WIDTH + 10), 0, 0]
});
return (
Expand All @@ -246,12 +242,12 @@ export default class RoomItem extends React.Component {
>
{isRead ? (
<View style={styles.actionView}>
<CustomIcon size={15} name='flag' color='white' />
<CustomIcon size={20} name='flag' color='white' />
<Text style={styles.actionText}>{I18n.t('Unread')}</Text>
</View>
) : (
<View style={styles.actionView}>
<CustomIcon size={15} name='check' color='white' />
<CustomIcon size={20} name='check' color='white' />
<Text style={styles.actionText}>{I18n.t('Read')}</Text>
</View>
)}
Expand All @@ -262,23 +258,24 @@ export default class RoomItem extends React.Component {
};

renderRightActions = () => {
const { favorite } = this.props;
const { width } = Dimensions.get('window');
const { favorite, width } = this.props;
const halfWidth = width / 2;
const trans = this.rowTranslation.interpolate({
inputRange: [-OPTION_WIDTH, 0],
outputRange: [width - OPTION_WIDTH, width]
});
const iconHideTrans = this.rowTranslation.interpolate({
inputRange: [-(ACTION_OFFSET - 20), -2 * OPTION_WIDTH, 0],
inputRange: [-(halfWidth - 20), -2 * OPTION_WIDTH, 0],
outputRange: [0, 0, -OPTION_WIDTH]
});
const iconFavWidth = this.rowTranslation.interpolate({
inputRange: [-(ACTION_OFFSET + 1), -ACTION_OFFSET, -(ACTION_OFFSET - 20), -2 * OPTION_WIDTH, 0],
outputRange: [0, 0, OPTION_WIDTH + 20, OPTION_WIDTH, OPTION_WIDTH]
inputRange: [-halfWidth, -2 * OPTION_WIDTH, 0],
outputRange: [0, OPTION_WIDTH, OPTION_WIDTH],
extrapolate: 'clamp'
});
const iconHideWidth = this.rowTranslation.interpolate({
inputRange: [-(ACTION_OFFSET + 1), -ACTION_OFFSET, -(ACTION_OFFSET - 20), -2 * OPTION_WIDTH, 0],
outputRange: [(ACTION_OFFSET + 1), ACTION_OFFSET, OPTION_WIDTH + 20, OPTION_WIDTH, OPTION_WIDTH]
inputRange: [-width, -halfWidth, -2 * OPTION_WIDTH, 0],
outputRange: [width, halfWidth, OPTION_WIDTH, OPTION_WIDTH]
});
return (
<Animated.View
Expand All @@ -293,12 +290,12 @@ export default class RoomItem extends React.Component {
<RectButton style={[styles.actionButtonRightFav]} onPress={this.toggleFav}>
{favorite ? (
<View style={styles.actionView}>
<CustomIcon size={17} name='Star-filled' color='white' />
<CustomIcon size={20} name='Star-filled' color='white' />
<Text style={styles.actionText}>{I18n.t('Unfavorite')}</Text>
</View>
) : (
<View style={styles.actionView}>
<CustomIcon size={17} name='star' color='white' />
<CustomIcon size={20} name='star' color='white' />
<Text style={styles.actionText}>{I18n.t('Favorite')}</Text>
</View>
)}
Expand All @@ -314,7 +311,7 @@ export default class RoomItem extends React.Component {
onPress={this.handleHideButtonPress}
>
<View style={styles.actionView}>
<CustomIcon size={15} name='eye-off' color='white' />
<CustomIcon size={20} name='eye-off' color='white' />
<Text style={styles.actionText}>{I18n.t('Hide')}</Text>
</View>
</RectButton>
Expand All @@ -332,7 +329,7 @@ export default class RoomItem extends React.Component {

render() {
const {
unread, userMentions, name, _updatedAt, alert, testID, height, type, avatarSize, baseUrl, userId, username, token, onPress, id, prid, showLastMessage, lastMessage
unread, userMentions, name, _updatedAt, alert, testID, height, type, avatarSize, baseUrl, userId, username, token, id, prid, showLastMessage, lastMessage
} = this.props;

const date = this.formatDate(_updatedAt);
Expand All @@ -358,7 +355,7 @@ export default class RoomItem extends React.Component {
onGestureEvent={this._onGestureEvent}
onHandlerStateChange={this._onHandlerStateChange}
>
<Animated.View style={styles.upperContainer}>
<View style={styles.upperContainer}>
{this.renderLeftActions()}
{this.renderRightActions()}
<Animated.View
Expand All @@ -369,10 +366,11 @@ export default class RoomItem extends React.Component {
}
>
<RectButton
onPress={onPress}
onPress={this.onPress}
activeOpacity={0.8}
underlayColor='#e1e5e8'
testID={testID}
style={styles.button}
>
<View
style={[styles.container, height && { height }]}
Expand All @@ -393,7 +391,7 @@ export default class RoomItem extends React.Component {
</View>
</RectButton>
</Animated.View>
</Animated.View>
</View>
</PanGestureHandler>
);
}
Expand Down
12 changes: 8 additions & 4 deletions app/presentation/RoomItem/styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ export const ROW_HEIGHT = 75 * PixelRatio.getFontScale();

export default StyleSheet.create({
container: {
backgroundColor: COLOR_WHITE,
flexDirection: 'row',
alignItems: 'center',
paddingLeft: 14,
height: ROW_HEIGHT
},
button: {
backgroundColor: COLOR_WHITE
},
centerContainer: {
flex: 1,
paddingVertical: 10,
Expand Down Expand Up @@ -96,10 +98,12 @@ export default StyleSheet.create({
marginRight: 10
},
actionText: {
color: 'white',
fontSize: 14,
color: COLOR_WHITE,
fontSize: 15,
backgroundColor: 'transparent',
justifyContent: 'center'
justifyContent: 'center',
marginTop: 4,
...sharedStyles.textSemibold
},
actionButtonLeft: {
flex: 1,
Expand Down
Loading