diff --git a/.eslintrc.js b/.eslintrc.js index f7cb61726..d25494a16 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -37,6 +37,7 @@ module.exports = { "jsx-quotes": [2, "prefer-single"], "jsx-a11y/href-no-hash": 0, "import/prefer-default-export": 0, + "camelcase": 0, "no-underscore-dangle": 0, "no-return-assign": 0, "no-param-reassign": 0, diff --git a/__tests__/__snapshots__/RoomItem.js.snap b/__tests__/__snapshots__/RoomItem.js.snap index 3eee42a6f..17d244018 100644 --- a/__tests__/__snapshots__/RoomItem.js.snap +++ b/__tests__/__snapshots__/RoomItem.js.snap @@ -4,8 +4,8 @@ exports[`render channel 1`] = ` @@ -132,8 +128,8 @@ exports[`render no icon 1`] = ` @@ -260,8 +252,8 @@ exports[`render private group 1`] = ` @@ -389,8 +377,8 @@ exports[`render unread +999 1`] = ` @@ -526,8 +510,8 @@ exports[`render unread 1`] = ` @@ -663,8 +643,8 @@ exports[`renders correctly 1`] = ` diff --git a/__tests__/__snapshots__/Storyshots.test.js.snap b/__tests__/__snapshots__/Storyshots.test.js.snap index 325faeffe..b51b4c8b9 100644 --- a/__tests__/__snapshots__/Storyshots.test.js.snap +++ b/__tests__/__snapshots__/Storyshots.test.js.snap @@ -23,7 +23,7 @@ exports[`Storyshots Avatar avatar 1`] = ` > @@ -268,8 +264,8 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` @@ -382,8 +374,8 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` @@ -514,8 +502,8 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` @@ -648,8 +632,8 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` @@ -780,8 +760,8 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` @@ -912,8 +888,8 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` @@ -1044,8 +1016,8 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` @@ -1176,8 +1144,8 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` @@ -1288,8 +1252,8 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` @@ -1400,8 +1360,8 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` diff --git a/app/containers/Avatar.js b/app/containers/Avatar.js index 7fe9b5ae6..4ce3e0bca 100644 --- a/app/containers/Avatar.js +++ b/app/containers/Avatar.js @@ -58,7 +58,7 @@ class Avatar extends React.PureComponent { ); return ( - {initials} + {initials} {image} ); } diff --git a/app/containers/MessageBox/index.js b/app/containers/MessageBox/index.js index 1c585a840..6aadc3870 100644 --- a/app/containers/MessageBox/index.js +++ b/app/containers/MessageBox/index.js @@ -54,9 +54,27 @@ export default class MessageBox extends React.Component { get leftButtons() { const { editing } = this.props; if (editing) { - return this.editCancel()} />; + return ( this.editCancel()} + />); } - return !this.state.emoji ? this.openEmoji()} name='md-happy' /> : this.openEmoji()} style={styles.actionButtons} name='md-sad' />; + return !this.state.emoji ? ( this.openEmoji()} + accessibilityLabel='Open emoji selector' + accessibilityTraits='button' + name='md-happy' + />) : ( this.openEmoji()} + style={styles.actionButtons} + accessibilityLabel='Close emoji selector' + accessibilityTraits='button' + name='md-sad' + />); } get rightButtons() { const icons = []; @@ -66,6 +84,8 @@ export default class MessageBox extends React.Component { style={[styles.actionButtons, { color: '#1D74F5' }]} name='send' key='sendIcon' + accessibilityLabel='Send message' + accessibilityTraits='button' onPress={() => this.submit(this.component._lastNativeText)} />); } @@ -73,6 +93,8 @@ export default class MessageBox extends React.Component { style={[styles.actionButtons, { color: '#2F343D', fontSize: 16 }]} name='plus' key='fileIcon' + accessibilityLabel='Message actions' + accessibilityTraits='button' onPress={() => this.addFile()} />); return icons; diff --git a/app/containers/message/index.js b/app/containers/message/index.js index 9f4d8b9d6..f5b35e819 100644 --- a/app/containers/message/index.js +++ b/app/containers/message/index.js @@ -2,6 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { View, StyleSheet, TouchableOpacity, Text } from 'react-native'; import { connect } from 'react-redux'; +import moment from 'moment'; import { actionsShow } from '../../actions/messages'; import Image from './Image'; @@ -114,11 +115,14 @@ export default class Message extends React.Component { const username = item.alias || item.u.username; const isEditing = message._id === item._id && editing; + const accessibilityLabel = `Message from ${ item.alias || item.u.username } at ${ moment(item.ts).format(this.props.Message_TimeFormat) }, ${ this.props.item.msg }`; + return ( this.onLongPress()} disabled={this.isDeleted()} style={[styles.message, extraStyle, isEditing ? styles.editing : null]} + accessibilityLabel={accessibilityLabel} > navigation.navigate('AddServer')} style={{ width: 50, alignItems: 'center' }} + accessibilityLabel='Add server' + accessibilityTraits='button' > @@ -68,7 +70,9 @@ const PublicRoutes = StackNavigator( } }, { - + navigationOptions: { + headerTitleAllowFontScaling: false + } } ); diff --git a/app/presentation/RoomItem.js b/app/presentation/RoomItem.js index 3cf02dd65..573e79f7c 100644 --- a/app/presentation/RoomItem.js +++ b/app/presentation/RoomItem.js @@ -6,11 +6,9 @@ import Avatar from '../containers/Avatar'; const styles = StyleSheet.create({ container: { - // flex: 1, flexDirection: 'row', - paddingLeft: 16, - paddingRight: 16, - height: 56, + paddingHorizontal: 16, + paddingVertical: 10, alignItems: 'center' }, number: { @@ -30,10 +28,8 @@ const styles = StyleSheet.create({ marginRight: 4 }, roomName: { - paddingTop: 10, flex: 1, fontSize: 16, - height: 16, color: '#444' }, alert: { @@ -45,7 +41,7 @@ const styles = StyleSheet.create({ update: { flex: 1, fontSize: 10, - height: 10, + // height: 10, color: '#888' } }); @@ -69,8 +65,8 @@ export default class RoomItem extends React.PureComponent { } formatDate = date => moment(date).calendar(null, { - lastDay: 'dddd', - sameDay: 'HH:mm', + lastDay: '[Yesterday]', + sameDay: 'h:mm A', lastWeek: 'dddd', sameElse: 'MMM D' }) @@ -100,12 +96,27 @@ export default class RoomItem extends React.PureComponent { favorite, alert, unread, userMentions, name, _updatedAt } = this.props; + const date = this.formatDate(_updatedAt); + + let accessibilityLabel = name; + if (unread === 1) { + accessibilityLabel += `, ${ unread } alert`; + } else if (unread > 1) { + accessibilityLabel += `, ${ unread } alerts`; + } + + if (userMentions > 0) { + accessibilityLabel += ', you were mentioned'; + } + + accessibilityLabel += `, last message ${ date }`; + return ( - + {this.icon} { name } - {_updatedAt ? { this.formatDate(_updatedAt) } : null} + {_updatedAt ? { date } : null} {this.renderNumber(unread, userMentions)} diff --git a/app/views/ForgotPasswordView.js b/app/views/ForgotPasswordView.js index 92f28cbce..2f40ee9eb 100644 --- a/app/views/ForgotPasswordView.js +++ b/app/views/ForgotPasswordView.js @@ -88,11 +88,11 @@ class ForgotPasswordView extends React.Component { /> - RESET PASSWORD + RESET PASSWORD - BACK TO LOGIN + BACK TO LOGIN {this.props.login.failure && {this.props.login.error.reason}} diff --git a/app/views/ListServerView.js b/app/views/ListServerView.js index 90e4d99e4..30bf7ea43 100644 --- a/app/views/ListServerView.js +++ b/app/views/ListServerView.js @@ -158,6 +158,7 @@ export default class ListServerView extends React.Component { { this.onPressItem(item); }} + adjustsFontSizeToFit > {item.id} diff --git a/app/views/LoginView.js b/app/views/LoginView.js index ccff7a763..f1f213ca8 100644 --- a/app/views/LoginView.js +++ b/app/views/LoginView.js @@ -3,7 +3,7 @@ import React from 'react'; import Spinner from 'react-native-loading-spinner-overlay'; import PropTypes from 'prop-types'; -import { Keyboard, Text, TextInput, View, TouchableOpacity, SafeAreaView } from 'react-native'; +import { Keyboard, Text, TextInput, View, ScrollView, TouchableOpacity, SafeAreaView } from 'react-native'; import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; // import * as actions from '../actions'; @@ -88,7 +88,7 @@ class LoginView extends React.Component { contentContainerStyle={styles.container} keyboardVerticalOffset={128} > - + - LOGIN + LOGIN - REGISTER + REGISTER - FORGOT MY PASSWORD + FORGOT MY PASSWORD - + By proceeding you are agreeing to our Terms of Service and @@ -146,7 +146,7 @@ class LoginView extends React.Component { - + ); } diff --git a/app/views/RegisterView.js b/app/views/RegisterView.js index ed2625869..7f97e48d7 100644 --- a/app/views/RegisterView.js +++ b/app/views/RegisterView.js @@ -133,6 +133,7 @@ class RegisterView extends React.Component { style={[styles.button, this._valid() ? {} : { color: placeholderTextColor } ]} + accessibilityTraits='button' >REGISTER diff --git a/app/views/RoomView/Header/index.js b/app/views/RoomView/Header/index.js index 85485ac61..14492449a 100644 --- a/app/views/RoomView/Header/index.js +++ b/app/views/RoomView/Header/index.js @@ -57,14 +57,21 @@ export default class extends React.Component { isDirect = () => this.state.room && this.state.room.t === 'd'; - renderLeft = () => this.props.navigation.goBack(null)} tintColor='#292E35' />; + renderLeft = () => this.props.navigation.goBack(null)} tintColor='#292E35' title='Back' titleStyle={{ display: 'none' }} />; renderTitle() { if (!this.state.roomName) { return null; } + + let accessibilityLabel = this.state.roomName; + + if (this.isDirect()) { + accessibilityLabel += `, ${ this.getUserStatusLabel() }`; + } + return ( - + {this.isDirect() ? : null @@ -77,9 +84,9 @@ export default class extends React.Component { type={this.state.room.t} /> - {this.state.roomName} + {this.state.roomName} {this.isDirect() ? - {this.getUserStatusLabel()} + {this.getUserStatusLabel()} : null } @@ -92,6 +99,8 @@ export default class extends React.Component { {}} + accessibilityLabel='Room actions' + accessibilityTraits='button' > + this.props.navigation.navigate('DrawerOpen')} @@ -85,30 +98,43 @@ export default class extends React.Component { } renderTitle() { + if (this.state.searching) { + return null; + } + if (!this.props.user.username) { return null; } + + const accessibilityLabel = `${ this.props.user.username }, ${ this.getUserStatusLabel() }, double tap to change status`; + return ( - this.showModal()}> - + this.showModal()} accessibilityLabel={accessibilityLabel} accessibilityTraits='header'> + - {this.props.user.username} + {this.props.user.username} ); } renderRight() { + if (this.state.searching) { + return null; + } + return ( {Platform.OS === 'android' ? this.onPressSearchButton()} + accessibilityLabel='Search' + accessibilityTraits='button' > this.createChannel()} + accessibilityLabel='Create channel' + accessibilityTraits='button' > - {this.renderLeft()} - {this.renderTitle()} - {this.renderRight()} - - ); - } - renderSearch() { if (!this.state.searching) { return null; @@ -188,7 +203,9 @@ export default class extends React.Component { render() { return ( - {this.renderHeader()} + {this.renderLeft()} + {this.renderTitle()} + {this.renderRight()} {this.renderSearch()}