I18n (#312)
This commit is contained in:
parent
ed8ce28708
commit
466a57e6b1
|
@ -172,6 +172,7 @@ repositories {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
compile project(':react-native-i18n')
|
||||
compile project(':react-native-fabric')
|
||||
compile project(':react-native-audio')
|
||||
compile project(":reactnativekeyboardinput")
|
||||
|
|
|
@ -20,6 +20,7 @@ import com.wix.reactnativekeyboardinput.KeyboardInputPackage;
|
|||
import com.rnim.rn.audio.ReactNativeAudioPackage;
|
||||
import com.smixx.fabric.FabricPackage;
|
||||
import com.dylanvann.fastimage.FastImageViewPackage;
|
||||
import com.AlexanderZaytsev.RNI18n.RNI18nPackage;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
@ -51,7 +52,8 @@ public class MainApplication extends Application implements ReactApplication {
|
|||
new KeyboardInputPackage(MainApplication.this),
|
||||
new RocketChatNativePackage(),
|
||||
new FabricPackage(),
|
||||
new FastImageViewPackage()
|
||||
new FastImageViewPackage(),
|
||||
new RNI18nPackage()
|
||||
);
|
||||
}
|
||||
};
|
|
@ -1,4 +1,6 @@
|
|||
rootProject.name = 'RocketChatRN'
|
||||
include ':react-native-i18n'
|
||||
project(':react-native-i18n').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-i18n/android')
|
||||
include ':react-native-fast-image'
|
||||
project(':react-native-fast-image').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fast-image/android')
|
||||
include ':react-native-fabric'
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
import { StyleSheet, View, Text } from 'react-native';
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
bannerContainer: {
|
||||
backgroundColor: '#ddd'
|
||||
},
|
||||
bannerText: {
|
||||
textAlign: 'center',
|
||||
margin: 5
|
||||
}
|
||||
});
|
||||
|
||||
@connect(state => ({
|
||||
connecting: state.meteor.connecting,
|
||||
authenticating: state.login.isFetching,
|
||||
offline: !state.meteor.connected,
|
||||
logged: !!state.login.token
|
||||
}))
|
||||
|
||||
export default class Banner extends React.PureComponent {
|
||||
static propTypes = {
|
||||
connecting: PropTypes.bool,
|
||||
authenticating: PropTypes.bool,
|
||||
offline: PropTypes.bool
|
||||
}
|
||||
render() {
|
||||
const {
|
||||
connecting, authenticating, offline, logged
|
||||
} = this.props;
|
||||
|
||||
if (offline) {
|
||||
return (
|
||||
<View style={[styles.bannerContainer, { backgroundColor: 'red' }]}>
|
||||
<Text style={[styles.bannerText, { color: '#a00' }]}>offline...</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
if (connecting) {
|
||||
return (
|
||||
<View style={[styles.bannerContainer, { backgroundColor: '#0d0' }]}>
|
||||
<Text style={[styles.bannerText, { color: '#fff' }]}>Connecting...</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
if (authenticating) {
|
||||
return (
|
||||
<View style={[styles.bannerContainer, { backgroundColor: 'orange' }]}>
|
||||
<Text style={[styles.bannerText, { color: '#a00' }]}>Authenticating...</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
if (logged) {
|
||||
return this.props.children;
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={[styles.bannerContainer, { backgroundColor: 'orange' }]}>
|
||||
<Text style={[styles.bannerText, { color: '#a00' }]}>Not logged...</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -18,6 +18,7 @@ import {
|
|||
} from '../actions/messages';
|
||||
import { showToast } from '../utils/info';
|
||||
import RocketChat from '../lib/rocketchat';
|
||||
import I18n from '../i18n';
|
||||
|
||||
@connect(
|
||||
state => ({
|
||||
|
@ -86,50 +87,50 @@ export default class MessageActions extends React.Component {
|
|||
if (nextProps.showActions !== this.props.showActions && nextProps.showActions) {
|
||||
const { actionMessage } = nextProps;
|
||||
// Cancel
|
||||
this.options = ['Cancel'];
|
||||
this.options = [I18n.t('Cancel')];
|
||||
this.CANCEL_INDEX = 0;
|
||||
// Reply
|
||||
if (!this.isRoomReadOnly()) {
|
||||
this.options.push('Reply');
|
||||
this.options.push(I18n.t('Reply'));
|
||||
this.REPLY_INDEX = this.options.length - 1;
|
||||
}
|
||||
// Edit
|
||||
if (this.allowEdit(nextProps)) {
|
||||
this.options.push('Edit');
|
||||
this.options.push(I18n.t('Edit'));
|
||||
this.EDIT_INDEX = this.options.length - 1;
|
||||
}
|
||||
// Permalink
|
||||
this.options.push('Copy Permalink');
|
||||
this.options.push(I18n.t('Copy_Permalink'));
|
||||
this.PERMALINK_INDEX = this.options.length - 1;
|
||||
// Copy
|
||||
this.options.push('Copy Message');
|
||||
this.options.push(I18n.t('Copy_Message'));
|
||||
this.COPY_INDEX = this.options.length - 1;
|
||||
// Share
|
||||
this.options.push('Share Message');
|
||||
this.options.push(I18n.t('Share_Message'));
|
||||
this.SHARE_INDEX = this.options.length - 1;
|
||||
// Quote
|
||||
if (!this.isRoomReadOnly()) {
|
||||
this.options.push('Quote');
|
||||
this.options.push(I18n.t('Quote'));
|
||||
this.QUOTE_INDEX = this.options.length - 1;
|
||||
}
|
||||
// Star
|
||||
if (this.props.Message_AllowStarring) {
|
||||
this.options.push(actionMessage.starred ? 'Unstar' : 'Star');
|
||||
this.options.push(I18n.t(actionMessage.starred ? 'Unstar' : 'Star'));
|
||||
this.STAR_INDEX = this.options.length - 1;
|
||||
}
|
||||
// Pin
|
||||
if (this.props.Message_AllowPinning) {
|
||||
this.options.push(actionMessage.pinned ? 'Unpin' : 'Pin');
|
||||
this.options.push(I18n.t(actionMessage.pinned ? 'Unpin' : 'Pin'));
|
||||
this.PIN_INDEX = this.options.length - 1;
|
||||
}
|
||||
// Reaction
|
||||
if (!this.isRoomReadOnly() || this.canReactWhenReadOnly()) {
|
||||
this.options.push('Add Reaction');
|
||||
this.options.push(I18n.t('Add_Reaction'));
|
||||
this.REACTION_INDEX = this.options.length - 1;
|
||||
}
|
||||
// Delete
|
||||
if (this.allowDelete(nextProps)) {
|
||||
this.options.push('Delete');
|
||||
this.options.push(I18n.t('Delete'));
|
||||
this.DELETE_INDEX = this.options.length - 1;
|
||||
}
|
||||
setTimeout(() => {
|
||||
|
@ -141,7 +142,7 @@ export default class MessageActions extends React.Component {
|
|||
if (this.state.copyPermalink) {
|
||||
this.setState({ copyPermalink: false });
|
||||
await Clipboard.setString(nextProps.permalink);
|
||||
showToast('Permalink copied to clipboard!');
|
||||
showToast(I18n.t('Permalink_copied_to_clipboard'));
|
||||
this.props.permalinkClear();
|
||||
// quote
|
||||
} else if (this.state.quote) {
|
||||
|
@ -234,15 +235,15 @@ export default class MessageActions extends React.Component {
|
|||
|
||||
handleDelete() {
|
||||
Alert.alert(
|
||||
'Are you sure?',
|
||||
'You will not be able to recover this message!',
|
||||
I18n.t('Are_you_sure_question_mark'),
|
||||
I18n.t('You_will_not_be_able_to_recover_this_message'),
|
||||
[
|
||||
{
|
||||
text: 'Cancel',
|
||||
text: I18n.t('Cancel'),
|
||||
style: 'cancel'
|
||||
},
|
||||
{
|
||||
text: 'Yes, delete it!',
|
||||
text: I18n.t('Yes_action_it', { action: 'delete' }),
|
||||
style: 'destructive',
|
||||
onPress: () => this.props.deleteRequest(this.props.actionMessage)
|
||||
}
|
||||
|
@ -258,7 +259,7 @@ export default class MessageActions extends React.Component {
|
|||
|
||||
handleCopy = async() => {
|
||||
await Clipboard.setString(this.props.actionMessage.msg);
|
||||
showToast('Copied to clipboard!');
|
||||
showToast(I18n.t('Copied_to_clipboard'));
|
||||
}
|
||||
|
||||
handleShare = async() => {
|
||||
|
@ -336,7 +337,7 @@ export default class MessageActions extends React.Component {
|
|||
return (
|
||||
<ActionSheet
|
||||
ref={o => this.ActionSheet = o}
|
||||
title='Messages actions'
|
||||
title={I18n.t('Message_actions')}
|
||||
testID='message-actions'
|
||||
options={this.options}
|
||||
cancelButtonIndex={this.CANCEL_INDEX}
|
||||
|
|
|
@ -4,6 +4,7 @@ import { View, SafeAreaView, Platform, PermissionsAndroid, Text } from 'react-na
|
|||
import { AudioRecorder, AudioUtils } from 'react-native-audio';
|
||||
import Icon from 'react-native-vector-icons/MaterialIcons';
|
||||
import styles from './styles';
|
||||
import I18n from '../../i18n';
|
||||
|
||||
export const _formatTime = function(seconds) {
|
||||
let minutes = Math.floor(seconds / 60);
|
||||
|
@ -24,8 +25,8 @@ export default class extends React.PureComponent {
|
|||
}
|
||||
|
||||
const rationale = {
|
||||
title: 'Microphone Permission',
|
||||
message: 'Rocket Chat needs access to your microphone so you can send audio message.'
|
||||
title: I18n.t('Microphone_Permission'),
|
||||
message: I18n.t('Microphone_Permission_Message')
|
||||
};
|
||||
|
||||
const result = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.RECORD_AUDIO, rationale);
|
||||
|
@ -118,7 +119,7 @@ export default class extends React.PureComponent {
|
|||
style={[styles.actionButtons, { color: 'red' }]}
|
||||
name='clear'
|
||||
key='clear'
|
||||
accessibilityLabel='Cancel recording'
|
||||
accessibilityLabel={I18n.t('Cancel_recording')}
|
||||
accessibilityTraits='button'
|
||||
onPress={this.cancelAudioMessage}
|
||||
/>
|
||||
|
@ -127,7 +128,7 @@ export default class extends React.PureComponent {
|
|||
style={[styles.actionButtons, { color: 'green' }]}
|
||||
name='check'
|
||||
key='check'
|
||||
accessibilityLabel='Finish recording'
|
||||
accessibilityLabel={I18n.t('Finish_recording')}
|
||||
accessibilityTraits='button'
|
||||
onPress={this.finishAudioMessage}
|
||||
/>
|
||||
|
|
|
@ -19,6 +19,7 @@ import { emojis } from '../../emojis';
|
|||
import Recording from './Recording';
|
||||
import './EmojiKeyboard';
|
||||
import log from '../../utils/log';
|
||||
import I18n from '../../i18n';
|
||||
|
||||
const MENTIONS_TRACKING_TYPE_USERS = '@';
|
||||
const MENTIONS_TRACKING_TYPE_EMOJIS = ':';
|
||||
|
@ -107,7 +108,7 @@ export default class MessageBox extends React.PureComponent {
|
|||
return (<Icon
|
||||
style={styles.actionButtons}
|
||||
name='close'
|
||||
accessibilityLabel='Cancel editing'
|
||||
accessibilityLabel={I18n.t('Cancel_editing')}
|
||||
accessibilityTraits='button'
|
||||
onPress={() => this.editCancel()}
|
||||
testID='messagebox-cancel-editing'
|
||||
|
@ -116,14 +117,14 @@ export default class MessageBox extends React.PureComponent {
|
|||
return !this.state.showEmojiKeyboard ? (<Icon
|
||||
style={styles.actionButtons}
|
||||
onPress={() => this.openEmoji()}
|
||||
accessibilityLabel='Open emoji selector'
|
||||
accessibilityLabel={I18n.t('Open_emoji_selector')}
|
||||
accessibilityTraits='button'
|
||||
name='mood'
|
||||
testID='messagebox-open-emoji'
|
||||
/>) : (<Icon
|
||||
onPress={() => this.closeEmoji()}
|
||||
style={styles.actionButtons}
|
||||
accessibilityLabel='Close emoji selector'
|
||||
accessibilityLabel={I18n.t('Close_emoji_selector')}
|
||||
accessibilityTraits='button'
|
||||
name='keyboard'
|
||||
testID='messagebox-close-emoji'
|
||||
|
@ -137,7 +138,7 @@ export default class MessageBox extends React.PureComponent {
|
|||
style={[styles.actionButtons, { color: '#1D74F5' }]}
|
||||
name='send'
|
||||
key='sendIcon'
|
||||
accessibilityLabel='Send message'
|
||||
accessibilityLabel={I18n.t('Send message')}
|
||||
accessibilityTraits='button'
|
||||
onPress={() => this.submit(this.state.text)}
|
||||
testID='messagebox-send-message'
|
||||
|
@ -148,7 +149,7 @@ export default class MessageBox extends React.PureComponent {
|
|||
style={[styles.actionButtons, { color: '#1D74F5', paddingHorizontal: 10 }]}
|
||||
name='mic'
|
||||
key='micIcon'
|
||||
accessibilityLabel='Send audio message'
|
||||
accessibilityLabel={I18n.t('Send audio message')}
|
||||
accessibilityTraits='button'
|
||||
onPress={() => this.recordAudioMessage()}
|
||||
testID='messagebox-send-audio'
|
||||
|
@ -157,7 +158,7 @@ export default class MessageBox extends React.PureComponent {
|
|||
style={[styles.actionButtons, { color: '#2F343D', fontSize: 16 }]}
|
||||
name='plus'
|
||||
key='fileIcon'
|
||||
accessibilityLabel='Message actions'
|
||||
accessibilityLabel={I18n.t('Message actions')}
|
||||
accessibilityTraits='button'
|
||||
onPress={() => this.addFile()}
|
||||
testID='messagebox-actions'
|
||||
|
@ -169,18 +170,13 @@ export default class MessageBox extends React.PureComponent {
|
|||
const options = {
|
||||
maxHeight: 1960,
|
||||
maxWidth: 1960,
|
||||
quality: 0.8,
|
||||
customButtons: [{
|
||||
name: 'import', title: 'Import File From'
|
||||
}]
|
||||
quality: 0.8
|
||||
};
|
||||
ImagePicker.showImagePicker(options, (response) => {
|
||||
if (response.didCancel) {
|
||||
console.warn('User cancelled image picker');
|
||||
} else if (response.error) {
|
||||
log('ImagePicker Error', response.error);
|
||||
} else if (response.customButton) {
|
||||
console.warn('User tapped custom button: ', response.customButton);
|
||||
} else {
|
||||
const fileInfo = {
|
||||
name: response.fileName,
|
||||
|
@ -250,10 +246,10 @@ export default class MessageBox extends React.PureComponent {
|
|||
|
||||
_getFixedMentions(keyword) {
|
||||
if ('all'.indexOf(keyword) !== -1) {
|
||||
this.users = [{ _id: -1, username: 'all', desc: 'all' }, ...this.users];
|
||||
this.users = [{ _id: -1, username: 'all' }, ...this.users];
|
||||
}
|
||||
if ('here'.indexOf(keyword) !== -1) {
|
||||
this.users = [{ _id: -2, username: 'here', desc: 'active users' }, ...this.users];
|
||||
this.users = [{ _id: -2, username: 'here' }, ...this.users];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -419,7 +415,7 @@ export default class MessageBox extends React.PureComponent {
|
|||
onPress={() => this._onPressMention(item)}
|
||||
>
|
||||
<Text style={styles.fixedMentionAvatar}>{item.username}</Text>
|
||||
<Text>Notify {item.desc} in this room</Text>
|
||||
<Text>{item.username === 'here' ? I18n.t('Notify_active_in_this_room') : I18n.t('Notify_all_in_this_room')}</Text>
|
||||
</TouchableOpacity>
|
||||
)
|
||||
renderMentionEmoji = (item) => {
|
||||
|
@ -507,7 +503,7 @@ export default class MessageBox extends React.PureComponent {
|
|||
returnKeyType='default'
|
||||
keyboardType='twitter'
|
||||
blurOnSubmit={false}
|
||||
placeholder='New Message'
|
||||
placeholder={I18n.t('New_Message')}
|
||||
onChangeText={text => this.onChangeText(text)}
|
||||
value={this.state.text}
|
||||
underlineColorAndroid='transparent'
|
||||
|
|
|
@ -7,6 +7,7 @@ import { errorActionsHide } from '../actions/messages';
|
|||
import RocketChat from '../lib/rocketchat';
|
||||
import database from '../lib/realm';
|
||||
import protectedFunction from '../lib/methods/helpers/protectedFunction';
|
||||
import I18n from '../i18n';
|
||||
|
||||
@connect(
|
||||
state => ({
|
||||
|
@ -27,7 +28,7 @@ export default class MessageErrorActions extends React.Component {
|
|||
constructor(props) {
|
||||
super(props);
|
||||
this.handleActionPress = this.handleActionPress.bind(this);
|
||||
this.options = ['Cancel', 'Delete', 'Resend'];
|
||||
this.options = [I18n.t('Cancel'), I18n.t('Delete'), I18n.t('Resend')];
|
||||
this.CANCEL_INDEX = 0;
|
||||
this.DELETE_INDEX = 1;
|
||||
this.RESEND_INDEX = 2;
|
||||
|
@ -66,7 +67,7 @@ export default class MessageErrorActions extends React.Component {
|
|||
return (
|
||||
<ActionSheet
|
||||
ref={o => this.ActionSheet = o}
|
||||
title='Messages actions'
|
||||
title={I18n.t('Message_actions')}
|
||||
options={this.options}
|
||||
cancelButtonIndex={this.CANCEL_INDEX}
|
||||
destructiveButtonIndex={this.DELETE_INDEX}
|
||||
|
|
|
@ -7,6 +7,7 @@ import { DrawerActions } from 'react-navigation';
|
|||
import database from '../lib/realm';
|
||||
import { setServer } from '../actions/server';
|
||||
import { logout } from '../actions/login';
|
||||
import I18n from '../i18n';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
scrollView: {
|
||||
|
@ -115,9 +116,7 @@ export default class Sidebar extends Component {
|
|||
testID='sidebar-logout'
|
||||
>
|
||||
<View style={styles.serverItem}>
|
||||
<Text>
|
||||
Logout
|
||||
</Text>
|
||||
<Text>{I18n.t('Logout')}</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
<TouchableHighlight
|
||||
|
@ -128,9 +127,7 @@ export default class Sidebar extends Component {
|
|||
testID='sidebar-add-server'
|
||||
>
|
||||
<View style={styles.serverItem}>
|
||||
<Text>
|
||||
Add Server
|
||||
</Text>
|
||||
<Text>{I18n.t('Add_Server')}</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
</View>
|
||||
|
|
|
@ -2,6 +2,7 @@ import React from 'react';
|
|||
import PropTypes from 'prop-types';
|
||||
import { View, StyleSheet, Text, Keyboard, LayoutAnimation } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
import I18n from '../i18n';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
typing: {
|
||||
|
@ -31,7 +32,7 @@ export default class Typing extends React.Component {
|
|||
}
|
||||
get usersTyping() {
|
||||
const users = this.props.usersTyping.filter(_username => this.props.username !== _username);
|
||||
return users.length ? `${ users.join(' ,') } ${ users.length > 1 ? 'are' : 'is' } typing` : '';
|
||||
return users.length ? `${ users.join(' ,') } ${ users.length > 1 ? I18n.t('are_typing') : I18n.t('is_typing') }` : '';
|
||||
}
|
||||
render() {
|
||||
const { usersTyping } = this;
|
||||
|
|
|
@ -5,6 +5,7 @@ import Modal from 'react-native-modal';
|
|||
import Icon from 'react-native-vector-icons/MaterialIcons';
|
||||
import { connect } from 'react-redux';
|
||||
import Emoji from './Emoji';
|
||||
import I18n from '../../i18n';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
titleContainer: {
|
||||
|
@ -68,11 +69,11 @@ export default class ReactionsModal extends React.PureComponent {
|
|||
renderItem = (item) => {
|
||||
const count = item.usernames.length;
|
||||
let usernames = item.usernames.slice(0, 3)
|
||||
.map(username => (username.value === this.props.user.username ? 'you' : username.value)).join(', ');
|
||||
.map(username => (username.value === this.props.user.username ? I18n.t('you') : username.value)).join(', ');
|
||||
if (count > 3) {
|
||||
usernames = `${ usernames } and more ${ count - 3 }`;
|
||||
usernames = `${ usernames } ${ I18n.t('and_more') } ${ count - 3 }`;
|
||||
} else {
|
||||
usernames = usernames.replace(/,(?=[^,]*$)/, ' and');
|
||||
usernames = usernames.replace(/,(?=[^,]*$)/, ` ${ I18n.t('and') }`);
|
||||
}
|
||||
return (
|
||||
<View style={styles.itemContainer}>
|
||||
|
@ -86,7 +87,7 @@ export default class ReactionsModal extends React.PureComponent {
|
|||
</View>
|
||||
<View style={styles.peopleItemContainer}>
|
||||
<Text style={styles.reactCount}>
|
||||
{count === 1 ? '1 person' : `${ count } people`} reacted
|
||||
{count === 1 ? I18n.t('1_person_reacted') : I18n.t('N_people_reacted', { n: count })}
|
||||
</Text>
|
||||
<Text style={styles.peopleReacted}>{ usernames }</Text>
|
||||
</View>
|
||||
|
@ -113,7 +114,7 @@ export default class ReactionsModal extends React.PureComponent {
|
|||
size={20}
|
||||
onPress={onClose}
|
||||
/>
|
||||
<Text style={styles.title}>Reactions</Text>
|
||||
<Text style={styles.title}>{I18n.t('Reactions')}</Text>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
<View style={styles.listContainer}>
|
||||
|
|
|
@ -21,6 +21,7 @@ import styles from './styles';
|
|||
import { actionsShow, errorActionsShow, toggleReactionPicker, replyBroadcast } from '../../actions/messages';
|
||||
import messagesStatus from '../../constants/messagesStatus';
|
||||
import Touch from '../../utils/touch';
|
||||
import I18n from '../../i18n';
|
||||
|
||||
const SYSTEM_MESSAGES = [
|
||||
'r',
|
||||
|
@ -44,35 +45,35 @@ const getInfoMessage = ({
|
|||
t, role, msg, u
|
||||
}) => {
|
||||
if (t === 'rm') {
|
||||
return 'Message removed';
|
||||
return I18n.t('Message_removed');
|
||||
} else if (t === 'uj') {
|
||||
return 'Has joined the channel.';
|
||||
return I18n.t('Has_joined_the_channel');
|
||||
} else if (t === 'r') {
|
||||
return `Room name changed to: ${ msg } by ${ u.username }`;
|
||||
return I18n.t('Room_name_changed', { name: msg, userBy: u.username });
|
||||
} else if (t === 'message_pinned') {
|
||||
return 'Message pinned';
|
||||
return I18n.t('Message_pinned');
|
||||
} else if (t === 'ul') {
|
||||
return 'Has left the channel.';
|
||||
return I18n.t('Has_left_the_channel');
|
||||
} else if (t === 'ru') {
|
||||
return `User ${ msg } removed by ${ u.username }`;
|
||||
return I18n.t('User_removed_by', { userRemoved: msg, userBy: u.username });
|
||||
} else if (t === 'au') {
|
||||
return `User ${ msg } added by ${ u.username }`;
|
||||
return I18n.t('User_added_by', { userAdded: msg, userBy: u.username });
|
||||
} else if (t === 'user-muted') {
|
||||
return `User ${ msg } muted by ${ u.username }`;
|
||||
return I18n.t('User_muted_by', { userMuted: msg, userBy: u.username });
|
||||
} else if (t === 'user-unmuted') {
|
||||
return `User ${ msg } unmuted by ${ u.username }`;
|
||||
return I18n.t('User_unmuted_by', { userUnmuted: msg, userBy: u.username });
|
||||
} else if (t === 'subscription-role-added') {
|
||||
return `${ msg } was set ${ role } by ${ u.username }`;
|
||||
} else if (t === 'subscription-role-removed') {
|
||||
return `${ msg } is no longer ${ role } by ${ u.username }`;
|
||||
} else if (t === 'room_changed_description') {
|
||||
return `Room description changed to: ${ msg } by ${ u.username }`;
|
||||
return I18n.t('Room_changed_description', { description: msg, userBy: u.username });
|
||||
} else if (t === 'room_changed_announcement') {
|
||||
return `Room announcement changed to: ${ msg } by ${ u.username }`;
|
||||
return I18n.t('Room_changed_announcement', { announcement: msg, userBy: u.username });
|
||||
} else if (t === 'room_changed_topic') {
|
||||
return `Room topic changed to: ${ msg } by ${ u.username }`;
|
||||
return I18n.t('Room_changed_topic', { topic: msg, userBy: u.username });
|
||||
} else if (t === 'room_changed_privacy') {
|
||||
return `Room type changed to: ${ msg } by ${ u.username }`;
|
||||
return I18n.t('Room_changed_privacy', { type: msg, userBy: u.username });
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
@ -334,7 +335,7 @@ export default class Message extends React.Component {
|
|||
} = this.props;
|
||||
const username = item.alias || item.u.username;
|
||||
const isEditing = message._id === item._id && editing;
|
||||
const accessibilityLabel = `Message from ${ username } at ${ moment(item.ts).format(this.timeFormat) }, ${ this.props.item.msg }`;
|
||||
const accessibilityLabel = I18n.t('Message_accessibility', { user: username, time: moment(item.ts).format(this.timeFormat), message: this.props.item.msg });
|
||||
|
||||
return (
|
||||
<Touch
|
||||
|
|
|
@ -17,6 +17,9 @@ import RoomFilesView from '../../views/RoomFilesView';
|
|||
import RoomMembersView from '../../views/RoomMembersView';
|
||||
import RoomInfoView from '../../views/RoomInfoView';
|
||||
import RoomInfoEditView from '../../views/RoomInfoEditView';
|
||||
import I18n from '../../i18n';
|
||||
|
||||
const headerTintColor = '#292E35';
|
||||
|
||||
const AuthRoutes = createStackNavigator(
|
||||
{
|
||||
|
@ -29,92 +32,92 @@ const AuthRoutes = createStackNavigator(
|
|||
CreateChannel: {
|
||||
screen: CreateChannelView,
|
||||
navigationOptions: {
|
||||
title: 'Create Channel',
|
||||
headerTintColor: '#292E35'
|
||||
title: I18n.t('Create_Channel'),
|
||||
headerTintColor
|
||||
}
|
||||
},
|
||||
SelectedUsers: {
|
||||
screen: SelectedUsersView,
|
||||
navigationOptions: {
|
||||
title: 'Select Users',
|
||||
headerTintColor: '#292E35'
|
||||
title: I18n.t('Select_Users'),
|
||||
headerTintColor
|
||||
}
|
||||
},
|
||||
AddServer: {
|
||||
screen: NewServerView,
|
||||
navigationOptions: {
|
||||
title: 'New server',
|
||||
headerTintColor: '#292E35'
|
||||
title: I18n.t('New_Server'),
|
||||
headerTintColor
|
||||
}
|
||||
},
|
||||
RoomActions: {
|
||||
screen: RoomActionsView,
|
||||
navigationOptions: {
|
||||
title: 'Actions',
|
||||
headerTintColor: '#292E35'
|
||||
title: I18n.t('Actions'),
|
||||
headerTintColor
|
||||
}
|
||||
},
|
||||
StarredMessages: {
|
||||
screen: StarredMessagesView,
|
||||
navigationOptions: {
|
||||
title: 'Starred Messages',
|
||||
headerTintColor: '#292E35'
|
||||
title: I18n.t('Starred_Messages'),
|
||||
headerTintColor
|
||||
}
|
||||
},
|
||||
PinnedMessages: {
|
||||
screen: PinnedMessagesView,
|
||||
navigationOptions: {
|
||||
title: 'Pinned Messages',
|
||||
headerTintColor: '#292E35'
|
||||
title: I18n.t('Pinned_Messages'),
|
||||
headerTintColor
|
||||
}
|
||||
},
|
||||
MentionedMessages: {
|
||||
screen: MentionedMessagesView,
|
||||
navigationOptions: {
|
||||
title: 'Mentioned Messages',
|
||||
headerTintColor: '#292E35'
|
||||
title: I18n.t('Mentioned_Messages'),
|
||||
headerTintColor
|
||||
}
|
||||
},
|
||||
SnippetedMessages: {
|
||||
screen: SnippetedMessagesView,
|
||||
navigationOptions: {
|
||||
title: 'Snippet Messages',
|
||||
headerTintColor: '#292E35'
|
||||
title: I18n.t('Snippet_Messages'),
|
||||
headerTintColor
|
||||
}
|
||||
},
|
||||
SearchMessages: {
|
||||
screen: SearchMessagesView,
|
||||
navigationOptions: {
|
||||
title: 'Search Messages',
|
||||
headerTintColor: '#292E35'
|
||||
title: I18n.t('Search_Messages'),
|
||||
headerTintColor
|
||||
}
|
||||
},
|
||||
RoomFiles: {
|
||||
screen: RoomFilesView,
|
||||
navigationOptions: {
|
||||
title: 'Room Files',
|
||||
headerTintColor: '#292E35'
|
||||
title: I18n.t('Room_Files'),
|
||||
headerTintColor
|
||||
}
|
||||
},
|
||||
RoomMembers: {
|
||||
screen: RoomMembersView,
|
||||
navigationOptions: {
|
||||
title: 'Room Members',
|
||||
headerTintColor: '#292E35'
|
||||
title: I18n.t('Room_Members'),
|
||||
headerTintColor
|
||||
}
|
||||
},
|
||||
RoomInfo: {
|
||||
screen: RoomInfoView,
|
||||
navigationOptions: {
|
||||
title: 'Room Info',
|
||||
headerTintColor: '#292E35'
|
||||
title: I18n.t('Room_Info'),
|
||||
headerTintColor
|
||||
}
|
||||
},
|
||||
RoomInfoEdit: {
|
||||
screen: RoomInfoEditView,
|
||||
navigationOptions: {
|
||||
title: 'Room Info Edit',
|
||||
headerTintColor: '#292E35'
|
||||
title: I18n.t('Room_Info_Edit'),
|
||||
headerTintColor
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -13,6 +13,7 @@ import TermsServiceView from '../../views/TermsServiceView';
|
|||
import PrivacyPolicyView from '../../views/PrivacyPolicyView';
|
||||
import ForgotPasswordView from '../../views/ForgotPasswordView';
|
||||
import database from '../../lib/realm';
|
||||
import I18n from '../../i18n';
|
||||
|
||||
const hasServers = () => {
|
||||
const db = database.databases.serversDB.objects('servers');
|
||||
|
@ -24,12 +25,12 @@ const ServerStack = createStackNavigator({
|
|||
screen: ListServerView,
|
||||
navigationOptions({ navigation }) {
|
||||
return {
|
||||
title: 'Servers',
|
||||
title: I18n.t('Servers'),
|
||||
headerRight: (
|
||||
<TouchableOpacity
|
||||
onPress={() => navigation.navigate({ key: 'AddServer', routeName: 'AddServer' })}
|
||||
style={{ width: 50, alignItems: 'center' }}
|
||||
accessibilityLabel='Add server'
|
||||
accessibilityLabel={I18n.t('Add_Server')}
|
||||
accessibilityTraits='button'
|
||||
>
|
||||
<Icon name='plus' size={16} />
|
||||
|
@ -65,7 +66,7 @@ const LoginStack = createStackNavigator({
|
|||
ForgotPassword: {
|
||||
screen: ForgotPasswordView,
|
||||
navigationOptions: {
|
||||
title: 'Forgot my password',
|
||||
title: I18n.t('Forgot_my_password'),
|
||||
headerTintColor: '#292E35'
|
||||
}
|
||||
}
|
||||
|
@ -83,14 +84,14 @@ const RegisterStack = createStackNavigator({
|
|||
TermsService: {
|
||||
screen: TermsServiceView,
|
||||
navigationOptions: {
|
||||
title: 'Terms of service',
|
||||
title: I18n.t('Terms_of_Service'),
|
||||
headerTintColor: '#292E35'
|
||||
}
|
||||
},
|
||||
PrivacyPolicy: {
|
||||
screen: PrivacyPolicyView,
|
||||
navigationOptions: {
|
||||
title: 'Privacy policy',
|
||||
title: I18n.t('Privacy_Policy'),
|
||||
headerTintColor: '#292E35'
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
import I18n from 'react-native-i18n';
|
||||
import en from './locales/en';
|
||||
|
||||
I18n.fallbacks = true;
|
||||
|
||||
I18n.translations = {
|
||||
en
|
||||
};
|
||||
|
||||
export default I18n;
|
|
@ -0,0 +1,216 @@
|
|||
export default {
|
||||
'1_online_member': '1 online member',
|
||||
'1_person_reacted': '1 person reacted',
|
||||
Actions: 'Actions',
|
||||
Add_Reaction: 'Add Reaction',
|
||||
Add_Server: 'Add Server',
|
||||
Add_user: 'Add user',
|
||||
Alert: 'Alert',
|
||||
alert: 'alert',
|
||||
alerts: 'alerts',
|
||||
All_users_in_the_channel_can_write_new_messages: 'All users in the channel can write new messages',
|
||||
All: 'All',
|
||||
Allow_Reactions: 'Allow Reactions',
|
||||
and_more: 'and more',
|
||||
and: 'and',
|
||||
announcement: 'announcement',
|
||||
Announcement: 'Announcement',
|
||||
ARCHIVE: 'ARCHIVE',
|
||||
archive: 'archive',
|
||||
are_typing: 'are typing',
|
||||
Are_you_sure_question_mark: 'Are you sure?',
|
||||
Are_you_sure_you_want_to_leave_the_room: 'Are you sure you want to leave the room {{room}}?',
|
||||
Authenticating: 'Authenticating',
|
||||
Away: 'Away',
|
||||
Block_user: 'Block user',
|
||||
Broadcast_channel_Description: 'Only authorized users can write new messages, but the other users will be able to reply',
|
||||
Broadcast_Channel: 'Broadcast Channel',
|
||||
Busy: 'Busy',
|
||||
By_proceeding_you_are_agreeing: 'By proceeding you are agreeing to our',
|
||||
Cancel_editing: 'Cancel editing',
|
||||
Cancel_recording: 'Cancel recording',
|
||||
Cancel: 'Cancel',
|
||||
Channel_Name: 'Channel Name',
|
||||
Close_emoji_selector: 'Close emoji selector',
|
||||
Code: 'Code',
|
||||
Colaborative: 'Colaborative',
|
||||
Connect: 'Connect',
|
||||
Connected_to: 'Connected to',
|
||||
Connecting: 'Connecting',
|
||||
Copied_to_clipboard: 'Copied to clipboard!',
|
||||
Copy_Message: 'Copy Message',
|
||||
Copy_Permalink: 'Copy Permalink',
|
||||
Create_account: 'Create account',
|
||||
Create_Channel: 'Create Channel',
|
||||
Create: 'Create',
|
||||
Delete_Room_Warning: 'Deleting a room will delete all messages posted within the room. This cannot be undone.',
|
||||
delete: 'delete',
|
||||
Delete: 'Delete',
|
||||
DELETE: 'DELETE',
|
||||
description: 'description',
|
||||
Description: 'Description',
|
||||
Disable_notifications: 'Disable notifications',
|
||||
Do_you_really_want_to_key_this_room_question_mark: 'Do you really want to {{key}} this room?',
|
||||
edit: 'edit',
|
||||
Edit: 'Edit',
|
||||
Email_or_password_field_is_empty: 'Email or password field is empty',
|
||||
Email: 'Email',
|
||||
Enable_notifications: 'Enable notifications',
|
||||
Everyone_can_access_this_channel: 'Everyone can access this channel',
|
||||
Files: 'Files',
|
||||
Finish_recording: 'Finish recording',
|
||||
Forgot_my_password: 'Forgot my password',
|
||||
Forgot_password_If_this_email_is_registered: 'If this email is registered, we\'ll send instructions on how to reset your password. If you do not receive an email shortly, please come back and try again.',
|
||||
Forgot_password: 'Forgot password',
|
||||
Has_joined_the_channel: 'Has joined the channel',
|
||||
Has_left_the_channel: 'Has left the channel',
|
||||
I_have_an_account: 'I have an account',
|
||||
Invisible: 'Invisible',
|
||||
is_a_valid_RocketChat_instance: 'is a valid Rocket.Chat instance',
|
||||
is_not_a_valid_RocketChat_instance: 'is not a valid Rocket.Chat instance',
|
||||
is_typing: 'is typing',
|
||||
Just_invited_people_can_access_this_channel: 'Just invited people can access this channel',
|
||||
last_message: 'last message',
|
||||
Leave_channel: 'Leave channel',
|
||||
leave: 'leave',
|
||||
Loading_messages_ellipsis: 'Loading messages...',
|
||||
Login: 'Login',
|
||||
Logout: 'Logout',
|
||||
Members: 'Members',
|
||||
Mentioned_Messages: 'Mentioned Messages',
|
||||
mentioned: 'mentioned',
|
||||
Mentions: 'Mentions',
|
||||
Message_accessibility: 'Message from {{user}} at {{time}}: {{message}}',
|
||||
Message_actions: 'Message actions',
|
||||
Message_pinned: 'Message pinned',
|
||||
Message_removed: 'Message removed',
|
||||
Microphone_Permission_Message: 'Rocket Chat needs access to your microphone so you can send audio message.',
|
||||
Microphone_Permission: 'Microphone Permission',
|
||||
Mute: 'Mute',
|
||||
muted: 'muted',
|
||||
My_servers: 'My servers',
|
||||
N_online_members: '{{n}} online members',
|
||||
N_person_reacted: '{{n}} people reacted',
|
||||
Name: 'Name',
|
||||
New_in_RocketChat_question_mark: 'New in Rocket.Chat?',
|
||||
New_Message: 'New Message',
|
||||
New_Server: 'New Server',
|
||||
No_files: 'No files',
|
||||
No_mentioned_messages: 'No mentioned messages',
|
||||
No_pinned_messages: 'No pinned messages',
|
||||
No_snippeted_messages: 'No snippeted messages',
|
||||
No_starred_messages: 'No starred messages',
|
||||
No_announcement_provided: 'No announcement provided.',
|
||||
No_description_provided: 'No description provided.',
|
||||
No_topic_provided: 'No topic provided.',
|
||||
No_Message: 'No Message',
|
||||
No_Reactions: 'No Reactions',
|
||||
Not_logged: 'Not logged',
|
||||
Nothing_to_save: 'Nothing to save!',
|
||||
Notify_active_in_this_room: 'Notify active users in this room',
|
||||
Notify_all_in_this_room: 'Notify all in this room',
|
||||
Offline: 'Offline',
|
||||
Online: 'Online',
|
||||
Only_authorized_users_can_write_new_messages: 'Only authorized users can write new messages',
|
||||
Open_emoji_selector: 'Open emoji selector',
|
||||
Or_continue_using_social_accounts: 'Or continue using social accounts',
|
||||
Password: 'Password',
|
||||
Permalink_copied_to_clipboard: 'Permalink copied to clipboard!',
|
||||
Pin: 'Pin',
|
||||
Pinned_Messages: 'Pinned Messages',
|
||||
pinned: 'pinned',
|
||||
Pinned: 'Pinned',
|
||||
Privacy_Policy: ' Privacy Policy',
|
||||
Private_Channel: 'Private Channel',
|
||||
Private: 'Private',
|
||||
Public_Channel: 'Public Channel',
|
||||
Public: 'Public',
|
||||
Quote: 'Quote',
|
||||
Reactions_are_disabled: 'Reactions are disabled',
|
||||
Reactions_are_enabled: 'Reactions are enabled',
|
||||
Reactions: 'Reactions',
|
||||
Read_Only_Channel: 'Read Only Channel',
|
||||
Read_Only: 'Read Only',
|
||||
Register: 'Register',
|
||||
Repeat_Password: 'Repeat Password',
|
||||
Reply: 'Reply',
|
||||
Resend: 'Resend',
|
||||
Reset_password: 'Reset password',
|
||||
RESET: 'RESET',
|
||||
Roles: 'Roles',
|
||||
Room_actions: 'Room actions',
|
||||
Room_changed_announcement: 'Room announcement changed to: {{announcement}} by {{userBy}}',
|
||||
Room_changed_description: 'Room description changed to: {{description}} by {{userBy}}',
|
||||
Room_changed_privacy: 'Room type changed to: {{type}} by {{userBy}}',
|
||||
Room_changed_topic: 'Room topic changed to: {{topic}} by {{userBy}}',
|
||||
Room_Files: 'Room Files',
|
||||
Room_Info_Edit: 'Room Info Edit',
|
||||
Room_Info: 'Room Info',
|
||||
Room_Members: 'Room Members',
|
||||
Room_name_changed: 'Room name changed to: {{name}} by {{userBy}}',
|
||||
SAVE: 'SAVE',
|
||||
Search_Messages: 'Search Messages',
|
||||
Search: 'Search',
|
||||
Select_Users: 'Select Users',
|
||||
Send_audio_message: 'Send audio message',
|
||||
Send_message: 'Send message',
|
||||
Servers: 'Servers',
|
||||
Settings_succesfully_changed: 'Settings succesfully changed!',
|
||||
Share_Message: 'Share Message',
|
||||
Share: 'Share',
|
||||
Sign_in_your_server: 'Sign in your server',
|
||||
Sign_Up: 'Sign Up',
|
||||
Snippet_Messages: 'Snippet Messages',
|
||||
snippeted: 'snippeted',
|
||||
Snippets: 'Snippets',
|
||||
Some_field_is_invalid_or_empty: 'Some field is invalid or empty',
|
||||
Star_room: 'Star room',
|
||||
Star: 'Star',
|
||||
Starred_Messages: 'Starred Messages',
|
||||
starred: 'starred',
|
||||
Starred: 'Starred',
|
||||
Start_of_conversation: 'Start of conversation',
|
||||
Submit: 'Submit',
|
||||
tap_to_change_status: 'tap to change status',
|
||||
Tap_to_view_servers_list: 'Tap to view servers list',
|
||||
Terms_of_Service: ' Terms of Service ',
|
||||
There_was_an_error_while_saving_settings: 'There was an error while saving settings!',
|
||||
This_room_is_blocked: 'This room is blocked',
|
||||
This_room_is_read_only: 'This room is read only',
|
||||
Timezone: 'Timezone',
|
||||
topic: 'topic',
|
||||
Topic: 'Topic',
|
||||
Type_the_channel_name_here: 'Type the channel name here',
|
||||
unarchive: 'unarchive',
|
||||
UNARCHIVE: 'UNARCHIVE',
|
||||
Unblock_user: 'Unblock user',
|
||||
Unmute: 'Unmute',
|
||||
unmuted: 'unmuted',
|
||||
Unpin: 'Unpin',
|
||||
unread_messages: 'unread messages',
|
||||
Unstar: 'Unstar',
|
||||
User_added_by: 'User {{userAdded}} added by {{userBy}}',
|
||||
User_has_been_key: 'User has been {{key}}!',
|
||||
User_is_no_longer_role_by_: '{{user}} is no longer {{role}} by {{userBy}}',
|
||||
User_muted_by: 'User {{userMuted}} muted by {{userBy}}',
|
||||
User_removed_by: 'User {{userRemoved}} removed by {{userBy}}',
|
||||
User_unmuted_by: 'User {{userUnmuted}} unmuted by {{userBy}}',
|
||||
User_was_set_role_by_: '{{user}} was set {{role}} by {{userBy}}',
|
||||
Username_is_empty: 'Username is empty',
|
||||
Username: 'Username',
|
||||
Validating: 'Validating',
|
||||
Video_call: 'Video call',
|
||||
Voice_call: 'Voice call',
|
||||
Welcome_title_pt_1: 'Prepare to take off with',
|
||||
Welcome_title_pt_2: 'the ultimate chat platform',
|
||||
Yes_action_it: 'Yes, {{action}} it!',
|
||||
Yesterday: 'Yesterday',
|
||||
You_are_in_preview_mode: 'You are in preview mode',
|
||||
You_are_offline: 'You are offline',
|
||||
You_can_search_using_RegExp_eg: 'You can search using RegExp. e.g. `/^text$/i`',
|
||||
You_colon: 'You: ',
|
||||
you_were_mentioned: 'you were mentioned',
|
||||
You_will_not_be_able_to_recover_this_message: 'You will not be able to recover this message!',
|
||||
you: 'you',
|
||||
Your_server: 'Your server'
|
||||
};
|
|
@ -2,7 +2,6 @@ import normalizeMessage from './normalizeMessage';
|
|||
// TODO: delete and update
|
||||
|
||||
export const merge = (subscription, room) => {
|
||||
subscription.muted = [];
|
||||
if (room) {
|
||||
if (room.rid) {
|
||||
subscription.rid = room.rid;
|
||||
|
@ -19,7 +18,9 @@ export const merge = (subscription, room) => {
|
|||
subscription.broadcast = room.broadcast;
|
||||
|
||||
if (room.muted && room.muted.length) {
|
||||
subscription.muted = room.muted.filter(user => user).map(user => ({ value: user }));
|
||||
subscription.muted = room.muted.map(user => ({ value: user }));
|
||||
} else {
|
||||
subscription.muted = [];
|
||||
}
|
||||
}
|
||||
if (subscription.roles && subscription.roles.length) {
|
||||
|
|
|
@ -4,13 +4,13 @@ import PropTypes from 'prop-types';
|
|||
import { View, Text, StyleSheet, ViewPropTypes } from 'react-native';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import { connect } from 'react-redux';
|
||||
// import SimpleMarkdown from 'simple-markdown';
|
||||
|
||||
import Avatar from '../containers/Avatar';
|
||||
import Status from '../containers/status';
|
||||
import Touch from '../utils/touch/index'; //eslint-disable-line
|
||||
import Markdown from '../containers/message/Markdown';
|
||||
import RoomTypeIcon from '../containers/RoomTypeIcon';
|
||||
import I18n from '../i18n';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
|
@ -98,36 +98,6 @@ const styles = StyleSheet.create({
|
|||
marginTop: 3
|
||||
}
|
||||
});
|
||||
// const markdownStyle = { block: { marginBottom: 0, flexWrap: 'wrap', flexDirection: 'row' } };
|
||||
|
||||
// const parseInline = (parse, content, state) => {
|
||||
// const isCurrentlyInline = state.inline || false;
|
||||
// state.inline = true;
|
||||
// const result = parse(content, state);
|
||||
// state.inline = isCurrentlyInline;
|
||||
// return result;
|
||||
// };
|
||||
// const parseCaptureInline = (capture, parse, state) => ({ content: parseInline(parse, capture[1], state) });
|
||||
// const customRules = {
|
||||
// strong: {
|
||||
// order: -4,
|
||||
// match: SimpleMarkdown.inlineRegex(/^\*\*([\s\S]+?)\*\*(?!\*)/),
|
||||
// parse: parseCaptureInline,
|
||||
// react: (node, output, state) => ({
|
||||
// type: 'strong',
|
||||
// key: state.key,
|
||||
// props: {
|
||||
// children: output(node.content, state)
|
||||
// }
|
||||
// })
|
||||
// },
|
||||
// text: {
|
||||
// order: -3,
|
||||
// match: SimpleMarkdown.inlineRegex(/^[\s\S]+?(?=[^0-9A-Za-z\s\u00c0-\uffff]|\n\n| {2,}\n|\w+:\S|$)/),
|
||||
// parse: capture => ({ content: capture[0] }),
|
||||
// react: node => node.content
|
||||
// }
|
||||
// };
|
||||
|
||||
const renderNumber = (unread, userMentions) => {
|
||||
if (!unread || unread <= 0) {
|
||||
|
@ -207,13 +177,13 @@ export default class RoomItem extends React.Component {
|
|||
return '';
|
||||
}
|
||||
if (!lastMessage) {
|
||||
return 'No Message';
|
||||
return I18n.t('No_Message');
|
||||
}
|
||||
|
||||
let prefix = '';
|
||||
|
||||
if (lastMessage.u.username === this.props.user.username) {
|
||||
prefix = 'You: ';
|
||||
prefix = I18n.t('You_colon');
|
||||
} else if (type !== 'd') {
|
||||
prefix = `${ lastMessage.u.username }: `;
|
||||
}
|
||||
|
@ -234,7 +204,7 @@ export default class RoomItem extends React.Component {
|
|||
}
|
||||
|
||||
formatDate = date => moment(date).calendar(null, {
|
||||
lastDay: '[Yesterday]',
|
||||
lastDay: `[${ I18n.t('Yesterday') }]`,
|
||||
sameDay: 'h:mm A',
|
||||
lastWeek: 'dddd',
|
||||
sameElse: 'MMM D'
|
||||
|
@ -249,17 +219,17 @@ export default class RoomItem extends React.Component {
|
|||
|
||||
let accessibilityLabel = name;
|
||||
if (unread === 1) {
|
||||
accessibilityLabel += `, ${ unread } alert`;
|
||||
accessibilityLabel += `, ${ unread } ${ I18n.t('alert') }`;
|
||||
} else if (unread > 1) {
|
||||
accessibilityLabel += `, ${ unread } alerts`;
|
||||
accessibilityLabel += `, ${ unread } ${ I18n.t('alerts') }`;
|
||||
}
|
||||
|
||||
if (userMentions > 0) {
|
||||
accessibilityLabel += ', you were mentioned';
|
||||
accessibilityLabel += `, ${ I18n.t('you_were_mentioned') }`;
|
||||
}
|
||||
|
||||
if (date) {
|
||||
accessibilityLabel += `, last message ${ date }`;
|
||||
accessibilityLabel += `, ${ I18n.t('last_message') } ${ date }`;
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
@ -98,7 +98,7 @@ const handleReplyBroadcast = function* handleReplyBroadcast({ message }) {
|
|||
}
|
||||
yield delay(100);
|
||||
const server = yield select(state => state.server.server);
|
||||
const msg = `[ ](${ server }/direct/${ username }?msg=${ message._id })`;
|
||||
const msg = `[ ](${ server }/direct/${ username }?msg=${ message._id }) `;
|
||||
yield put(setInput({ msg }));
|
||||
} catch (e) {
|
||||
log('handleReplyBroadcast', e);
|
||||
|
|
|
@ -11,6 +11,7 @@ import styles from './Styles';
|
|||
import KeyboardView from '../presentation/KeyboardView';
|
||||
import scrollPersistTaps from '../utils/scrollPersistTaps';
|
||||
import Button from '../containers/Button';
|
||||
import I18n from '../i18n';
|
||||
|
||||
@connect(
|
||||
state => ({
|
||||
|
@ -22,9 +23,6 @@ import Button from '../containers/Button';
|
|||
})
|
||||
)
|
||||
export default class CreateChannelView extends LoggedView {
|
||||
static navigationOptions = () => ({
|
||||
title: 'Create a New Channel'
|
||||
});
|
||||
static propTypes = {
|
||||
create: PropTypes.func.isRequired,
|
||||
createChannel: PropTypes.object.isRequired,
|
||||
|
@ -99,8 +97,8 @@ export default class CreateChannelView extends LoggedView {
|
|||
return this.renderSwitch({
|
||||
id: 'type',
|
||||
value: type,
|
||||
label: type ? 'Private Channel' : 'Public Channel',
|
||||
description: type ? 'Just invited people can access this channel' : 'Everyone can access this channel',
|
||||
label: type ? I18n.t('Private_Channel') : I18n.t('Public_Channel'),
|
||||
description: type ? I18n.t('Just_invited_people_can_access_this_channel') : I18n.t('Everyone_can_access_this_channel'),
|
||||
onValueChange: value => this.setState({ type: value })
|
||||
});
|
||||
}
|
||||
|
@ -110,8 +108,8 @@ export default class CreateChannelView extends LoggedView {
|
|||
return this.renderSwitch({
|
||||
id: 'readonly',
|
||||
value: readOnly,
|
||||
label: 'Read Only Channel',
|
||||
description: readOnly ? 'Only authorized users can write new messages' : 'All users in the channel can write new messages',
|
||||
label: I18n.t('Read_Only_Channel'),
|
||||
description: readOnly ? I18n.t('Only_authorized_users_can_write_new_messages') : I18n.t('All_users_in_the_channel_can_write_new_messages'),
|
||||
onValueChange: value => this.setState({ readOnly: value }),
|
||||
disabled: broadcast
|
||||
});
|
||||
|
@ -122,8 +120,8 @@ export default class CreateChannelView extends LoggedView {
|
|||
return this.renderSwitch({
|
||||
id: 'broadcast',
|
||||
value: broadcast,
|
||||
label: 'Broadcast Channel',
|
||||
description: 'Only authorized users can write new messages, but the other users will be able to reply',
|
||||
label: I18n.t('Broadcast_Channel'),
|
||||
description: I18n.t('Broadcast_channel_Description'),
|
||||
onValueChange: (value) => {
|
||||
this.setState({
|
||||
broadcast: value,
|
||||
|
@ -142,10 +140,10 @@ export default class CreateChannelView extends LoggedView {
|
|||
<ScrollView {...scrollPersistTaps} contentContainerStyle={styles.containerScrollView}>
|
||||
<SafeAreaView testID='create-channel-view'>
|
||||
<RCTextInput
|
||||
label='Channel Name'
|
||||
label={I18n.t('Channel_Name')}
|
||||
value={this.state.channelName}
|
||||
onChangeText={channelName => this.setState({ channelName })}
|
||||
placeholder='Type the channel name here'
|
||||
placeholder={I18n.t('Type_the_channel_name_here')}
|
||||
returnKeyType='done'
|
||||
autoFocus
|
||||
testID='create-channel-name'
|
||||
|
@ -156,7 +154,7 @@ export default class CreateChannelView extends LoggedView {
|
|||
{this.renderBroadcast()}
|
||||
<View style={styles.alignItemsFlexStart}>
|
||||
<Button
|
||||
title='Create'
|
||||
title={I18n.t('Create')}
|
||||
type='primary'
|
||||
onPress={this.submit}
|
||||
disabled={this.state.channelName.length === 0 || this.props.createChannel.isFetching}
|
||||
|
|
|
@ -12,6 +12,7 @@ import Loading from '../containers/Loading';
|
|||
import styles from './Styles';
|
||||
import { showErrorAlert } from '../utils/info';
|
||||
import scrollPersistTaps from '../utils/scrollPersistTaps';
|
||||
import I18n from '../i18n';
|
||||
|
||||
@connect(state => ({
|
||||
login: state.login
|
||||
|
@ -45,12 +46,7 @@ export default class ForgotPasswordView extends LoggedView {
|
|||
if (login.success) {
|
||||
this.props.navigation.goBack();
|
||||
setTimeout(() => {
|
||||
showErrorAlert(
|
||||
'If this email is registered, ' +
|
||||
'we\'ll send instructions on how to reset your password. ' +
|
||||
'If you do not receive an email shortly, please come back and try again.',
|
||||
'Alert'
|
||||
);
|
||||
showErrorAlert(I18n.t('Forgot_password_If_this_email_is_registered'), I18n.t('Alert'));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -85,8 +81,8 @@ export default class ForgotPasswordView extends LoggedView {
|
|||
<View style={styles.formContainer}>
|
||||
<TextInput
|
||||
inputStyle={this.state.invalidEmail ? { borderColor: 'red' } : {}}
|
||||
label='Email'
|
||||
placeholder='Email'
|
||||
label={I18n.t('Email')}
|
||||
placeholder={I18n.t('Email')}
|
||||
keyboardType='email-address'
|
||||
returnKeyType='next'
|
||||
onChangeText={email => this.validate(email)}
|
||||
|
@ -96,7 +92,7 @@ export default class ForgotPasswordView extends LoggedView {
|
|||
|
||||
<View style={styles.alignItemsFlexStart}>
|
||||
<Button
|
||||
title='Reset password'
|
||||
title={I18n.t('Reset_password')}
|
||||
type='primary'
|
||||
onPress={this.resetPassword}
|
||||
testID='forgot-password-view-submit'
|
||||
|
|
|
@ -12,6 +12,7 @@ import { setServer } from '../actions/server';
|
|||
import database from '../lib/realm';
|
||||
import Fade from '../animations/fade';
|
||||
import Touch from '../utils/touch';
|
||||
import I18n from '../i18n';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
view: {
|
||||
|
@ -141,7 +142,7 @@ class ListServerView extends LoggedView {
|
|||
|
||||
getState = () => {
|
||||
const sections = [{
|
||||
title: 'My servers',
|
||||
title: I18n.t('My_servers'),
|
||||
data: this.data
|
||||
}];
|
||||
//
|
||||
|
|
|
@ -15,6 +15,7 @@ import scrollPersistTaps from '../utils/scrollPersistTaps';
|
|||
import random from '../utils/random';
|
||||
import Button from '../containers/Button';
|
||||
import Loading from '../containers/Loading';
|
||||
import I18n from '../i18n';
|
||||
|
||||
const userAgentAndroid = 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1';
|
||||
const userAgent = Platform.OS === 'ios' ? 'UserAgent' : userAgentAndroid;
|
||||
|
@ -205,7 +206,7 @@ export default class LoginSignupView extends LoggedView {
|
|||
return (
|
||||
<View style={styles.servicesContainer}>
|
||||
<Text style={styles.servicesTitle}>
|
||||
Or continue using Social accounts
|
||||
{I18n.t('Or_continue_using_social_accounts')}
|
||||
</Text>
|
||||
<View style={sharedStyles.loginOAuthButtons} key='services'>
|
||||
{this.props.Accounts_OAuth_Facebook && this.props.services.facebook &&
|
||||
|
@ -284,20 +285,20 @@ export default class LoginSignupView extends LoggedView {
|
|||
style={sharedStyles.loginLogo}
|
||||
resizeMode='center'
|
||||
/>
|
||||
<Text style={[sharedStyles.loginText, styles.header, { color: '#81848A' }]}>Prepare to take off with</Text>
|
||||
<Text style={[sharedStyles.loginText, styles.header]}>the ultimate chat platform</Text>
|
||||
<Text style={[sharedStyles.loginText, styles.header, { color: '#81848A' }]}>{I18n.t('Welcome_title_pt_1')}</Text>
|
||||
<Text style={[sharedStyles.loginText, styles.header]}>{I18n.t('Welcome_title_pt_2')}</Text>
|
||||
<Image
|
||||
style={styles.planetImage}
|
||||
source={require('../static/images/planet.png')}
|
||||
/>
|
||||
<Button
|
||||
title='I have an account'
|
||||
title={I18n.t('I_have_an_account')}
|
||||
type='primary'
|
||||
onPress={() => this.props.navigation.navigate({ key: 'Login', routeName: 'Login' })}
|
||||
testID='welcome-view-login'
|
||||
/>
|
||||
<Button
|
||||
title='Create account'
|
||||
title={I18n.t('Create_account')}
|
||||
type='secondary'
|
||||
onPress={() => this.props.navigation.navigate({ key: 'Register', routeName: 'Register' })}
|
||||
testID='welcome-view-register'
|
||||
|
|
|
@ -15,6 +15,7 @@ import scrollPersistTaps from '../utils/scrollPersistTaps';
|
|||
import { showToast } from '../utils/info';
|
||||
import { COLOR_BUTTON_PRIMARY } from '../constants/colors';
|
||||
import LoggedView from './View';
|
||||
import I18n from '../i18n';
|
||||
|
||||
@connect(state => ({
|
||||
server: state.server.server,
|
||||
|
@ -44,7 +45,7 @@ export default class LoginView extends LoggedView {
|
|||
submit = async() => {
|
||||
const { username, password, code } = this.state;
|
||||
if (username.trim() === '' || password.trim() === '') {
|
||||
showToast('Email or password field is empty');
|
||||
showToast(I18n.t('Email_or_password_field_is_empty'));
|
||||
return;
|
||||
}
|
||||
Keyboard.dismiss();
|
||||
|
@ -62,9 +63,9 @@ export default class LoginView extends LoggedView {
|
|||
return (
|
||||
<TextInput
|
||||
inputRef={ref => this.codeInput = ref}
|
||||
label='Code'
|
||||
label={I18n.t('Code')}
|
||||
onChangeText={code => this.setState({ code })}
|
||||
placeholder='Code'
|
||||
placeholder={I18n.t('Code')}
|
||||
keyboardType='numeric'
|
||||
returnKeyType='done'
|
||||
autoCapitalize='none'
|
||||
|
@ -87,8 +88,8 @@ export default class LoginView extends LoggedView {
|
|||
<CloseModalButton navigation={this.props.navigation} />
|
||||
<Text style={[styles.loginText, styles.loginTitle]}>Login</Text>
|
||||
<TextInput
|
||||
label='Username'
|
||||
placeholder={this.props.Accounts_EmailOrUsernamePlaceholder || 'Username'}
|
||||
label={I18n.t('Username')}
|
||||
placeholder={this.props.Accounts_EmailOrUsernamePlaceholder || I18n.t('Username')}
|
||||
keyboardType='email-address'
|
||||
returnKeyType='next'
|
||||
iconLeft='at'
|
||||
|
@ -99,8 +100,8 @@ export default class LoginView extends LoggedView {
|
|||
|
||||
<TextInput
|
||||
inputRef={(e) => { this.password = e; }}
|
||||
label='Password'
|
||||
placeholder={this.props.Accounts_PasswordPlaceholder || 'Password'}
|
||||
label={I18n.t('Password')}
|
||||
placeholder={this.props.Accounts_PasswordPlaceholder || I18n.t('Password')}
|
||||
returnKeyType='done'
|
||||
iconLeft='key-variant'
|
||||
secureTextEntry
|
||||
|
@ -113,7 +114,7 @@ export default class LoginView extends LoggedView {
|
|||
|
||||
<View style={styles.alignItemsFlexStart}>
|
||||
<Button
|
||||
title='Login'
|
||||
title={I18n.t('Login')}
|
||||
type='primary'
|
||||
onPress={this.submit}
|
||||
testID='login-view-submit'
|
||||
|
@ -122,15 +123,15 @@ export default class LoginView extends LoggedView {
|
|||
style={[styles.loginText, { marginTop: 10 }]}
|
||||
testID='login-view-register'
|
||||
onPress={() => this.props.navigation.navigate('Register')}
|
||||
>New in Rocket.Chat?
|
||||
<Text style={{ color: COLOR_BUTTON_PRIMARY }}>Sign Up
|
||||
>{I18n.t('New_in_RocketChat_question_mark')}
|
||||
<Text style={{ color: COLOR_BUTTON_PRIMARY }}>{I18n.t('Sign_Up')}
|
||||
</Text>
|
||||
</Text>
|
||||
<Text
|
||||
style={[styles.loginText, { marginTop: 20, fontSize: 13 }]}
|
||||
onPress={() => this.props.navigation.navigate('ForgotPassword')}
|
||||
testID='login-view-forgot-password'
|
||||
>Forgot password
|
||||
>{I18n.t('Forgot_password')}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import { openMentionedMessages, closeMentionedMessages } from '../../actions/men
|
|||
import styles from './styles';
|
||||
import Message from '../../containers/message';
|
||||
import RCActivityIndicator from '../../containers/ActivityIndicator';
|
||||
import I18n from '../../i18n';
|
||||
|
||||
@connect(
|
||||
state => ({
|
||||
|
@ -74,7 +75,7 @@ export default class MentionedMessagesView extends LoggedView {
|
|||
|
||||
renderEmpty = () => (
|
||||
<View style={styles.listEmptyContainer} testID='mentioned-messages-view'>
|
||||
<Text>No mentioned messages</Text>
|
||||
<Text>{I18n.t('No_mentioned_messages')}</Text>
|
||||
</View>
|
||||
)
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import Button from '../containers/Button';
|
|||
import TextInput from '../containers/TextInput';
|
||||
import Loading from '../containers/Loading';
|
||||
import LoggedView from './View';
|
||||
import I18n from '../i18n';
|
||||
|
||||
@connect(state => ({
|
||||
validInstance: !state.server.failure && !state.server.connecting,
|
||||
|
@ -81,7 +82,7 @@ export default class NewServerView extends LoggedView {
|
|||
if (this.props.validating) {
|
||||
return (
|
||||
<Text style={[styles.validateText, styles.validatingText]}>
|
||||
Validating {this.state.text || 'open'} ...
|
||||
{I18n.t('Validating')} {this.state.text || 'open'} ...
|
||||
</Text>
|
||||
);
|
||||
}
|
||||
|
@ -89,13 +90,13 @@ export default class NewServerView extends LoggedView {
|
|||
if (this.props.validInstance) {
|
||||
return (
|
||||
<Text style={[styles.validateText, styles.validText]}>
|
||||
{this.state.url} is a valid Rocket.Chat instance
|
||||
{this.state.url} {I18n.t('is_a_valid_RocketChat_instance')}
|
||||
</Text>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Text style={[styles.validateText, styles.invalidText]}>
|
||||
{this.state.url} is not a valid Rocket.Chat instance
|
||||
{this.state.url} {I18n.t('is_not_a_valid_RocketChat_instance')}
|
||||
</Text>
|
||||
);
|
||||
}
|
||||
|
@ -109,11 +110,11 @@ export default class NewServerView extends LoggedView {
|
|||
>
|
||||
<ScrollView {...scrollPersistTaps} contentContainerStyle={styles.containerScrollView}>
|
||||
<SafeAreaView testID='new-server-view'>
|
||||
<Text style={[styles.loginText, styles.loginTitle]}>Sign in your server</Text>
|
||||
<Text style={[styles.loginText, styles.loginTitle]}>{I18n.t('Sign_in_your_server')}</Text>
|
||||
<TextInput
|
||||
inputRef={e => this.input = e}
|
||||
containerStyle={{ marginBottom: 5 }}
|
||||
label='Your server'
|
||||
label={I18n.t('Your_server')}
|
||||
placeholder={this.state.defaultServer}
|
||||
returnKeyType='done'
|
||||
onChangeText={this.onChangeText}
|
||||
|
@ -123,7 +124,7 @@ export default class NewServerView extends LoggedView {
|
|||
{this.renderValidation()}
|
||||
<View style={[styles.alignItemsFlexStart, { marginTop: 20 }]}>
|
||||
<Button
|
||||
title='Connect'
|
||||
title={I18n.t('Connect')}
|
||||
type='primary'
|
||||
onPress={this.submit}
|
||||
disabled={!validInstance}
|
||||
|
|
|
@ -10,10 +10,11 @@ import styles from './styles';
|
|||
import Message from '../../containers/message';
|
||||
import { togglePinRequest } from '../../actions/messages';
|
||||
import RCActivityIndicator from '../../containers/ActivityIndicator';
|
||||
import I18n from '../../i18n';
|
||||
|
||||
const PIN_INDEX = 0;
|
||||
const CANCEL_INDEX = 1;
|
||||
const options = ['Unpin', 'Cancel'];
|
||||
const options = [I18n.t('Unpin'), I18n.t('Cancel')];
|
||||
|
||||
@connect(
|
||||
state => ({
|
||||
|
@ -98,7 +99,7 @@ export default class PinnedMessagesView extends LoggedView {
|
|||
|
||||
renderEmpty = () => (
|
||||
<View style={styles.listEmptyContainer} testID='pinned-messages-view'>
|
||||
<Text>No pinned messages</Text>
|
||||
<Text>{I18n.t('No_pinned_messages')}</Text>
|
||||
</View>
|
||||
)
|
||||
|
||||
|
@ -138,7 +139,7 @@ export default class PinnedMessagesView extends LoggedView {
|
|||
<ActionSheet
|
||||
key='pinned-messages-view-action-sheet'
|
||||
ref={o => this.actionSheet = o}
|
||||
title='Actions'
|
||||
title={I18n.t('Actions')}
|
||||
options={options}
|
||||
cancelButtonIndex={CANCEL_INDEX}
|
||||
onPress={this.handleActionPress}
|
||||
|
|
|
@ -3,15 +3,11 @@ import PropTypes from 'prop-types';
|
|||
import { WebView } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
class PrivacyPolicyView extends React.Component {
|
||||
class PrivacyPolicyView extends React.PureComponent {
|
||||
static propTypes = {
|
||||
privacyPolicy: PropTypes.string
|
||||
}
|
||||
|
||||
static navigationOptions = () => ({
|
||||
title: 'Terms of service'
|
||||
});
|
||||
|
||||
render() {
|
||||
return (
|
||||
<WebView source={{ html: this.props.privacyPolicy }} />
|
||||
|
|
|
@ -13,6 +13,7 @@ import { showToast } from '../utils/info';
|
|||
import CloseModalButton from '../containers/CloseModalButton';
|
||||
import scrollPersistTaps from '../utils/scrollPersistTaps';
|
||||
import LoggedView from './View';
|
||||
import I18n from '../i18n';
|
||||
|
||||
@connect(state => ({
|
||||
server: state.server.server,
|
||||
|
@ -65,7 +66,7 @@ export default class RegisterView extends LoggedView {
|
|||
name, email, password, code
|
||||
} = this.state;
|
||||
if (!this.valid()) {
|
||||
showToast('Some field is invalid or empty');
|
||||
showToast(I18n.t('Some_field_is_invalid_or_empty'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -78,7 +79,7 @@ export default class RegisterView extends LoggedView {
|
|||
usernameSubmit = () => {
|
||||
const { username } = this.state;
|
||||
if (!username) {
|
||||
showToast('Username is empty');
|
||||
showToast(I18n.t('Username_is_empty'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -102,8 +103,8 @@ export default class RegisterView extends LoggedView {
|
|||
<View>
|
||||
<TextInput
|
||||
inputRef={(e) => { this.name = e; }}
|
||||
label={this.props.Accounts_NamePlaceholder || 'Name'}
|
||||
placeholder={this.props.Accounts_NamePlaceholder || 'Name'}
|
||||
label={this.props.Accounts_NamePlaceholder || I18n.t('Name')}
|
||||
placeholder={this.props.Accounts_NamePlaceholder || I18n.t('Name')}
|
||||
returnKeyType='next'
|
||||
iconLeft='account'
|
||||
onChangeText={name => this.setState({ name })}
|
||||
|
@ -112,8 +113,8 @@ export default class RegisterView extends LoggedView {
|
|||
/>
|
||||
<TextInput
|
||||
inputRef={(e) => { this.email = e; }}
|
||||
label={this.props.Accounts_EmailOrUsernamePlaceholder || 'Email'}
|
||||
placeholder={this.props.Accounts_EmailOrUsernamePlaceholder || 'Email'}
|
||||
label={this.props.Accounts_EmailOrUsernamePlaceholder || I18n.t('Email')}
|
||||
placeholder={this.props.Accounts_EmailOrUsernamePlaceholder || I18n.t('Email')}
|
||||
returnKeyType='next'
|
||||
keyboardType='email-address'
|
||||
iconLeft='email'
|
||||
|
@ -124,8 +125,8 @@ export default class RegisterView extends LoggedView {
|
|||
/>
|
||||
<TextInput
|
||||
inputRef={(e) => { this.password = e; }}
|
||||
label={this.props.Accounts_PasswordPlaceholder || 'Password'}
|
||||
placeholder={this.props.Accounts_PasswordPlaceholder || 'Password'}
|
||||
label={this.props.Accounts_PasswordPlaceholder || I18n.t('Password')}
|
||||
placeholder={this.props.Accounts_PasswordPlaceholder || I18n.t('Password')}
|
||||
returnKeyType='next'
|
||||
iconLeft='key-variant'
|
||||
secureTextEntry
|
||||
|
@ -140,8 +141,8 @@ export default class RegisterView extends LoggedView {
|
|||
this.state.confirmPassword &&
|
||||
this.state.confirmPassword !== this.state.password ? { borderColor: 'red' } : {}
|
||||
}
|
||||
label={this.props.Accounts_RepeatPasswordPlaceholder || 'Repeat Password'}
|
||||
placeholder={this.props.Accounts_RepeatPasswordPlaceholder || 'Repeat Password'}
|
||||
label={this.props.Accounts_RepeatPasswordPlaceholder || I18n.t('Repeat_Password')}
|
||||
placeholder={this.props.Accounts_RepeatPasswordPlaceholder || I18n.t('Repeat_Password')}
|
||||
returnKeyType='done'
|
||||
iconLeft='key-variant'
|
||||
secureTextEntry
|
||||
|
@ -152,13 +153,13 @@ export default class RegisterView extends LoggedView {
|
|||
|
||||
<View style={styles.alignItemsFlexStart}>
|
||||
<Text style={styles.loginTermsText}>
|
||||
By proceeding you are agreeing to our
|
||||
<Text style={styles.link} onPress={this.termsService}> Terms of Service </Text>
|
||||
and
|
||||
<Text style={styles.link} onPress={this.privacyPolicy}> Privacy Policy</Text>
|
||||
{I18n.t('By_proceeding_you_are_agreeing')}
|
||||
<Text style={styles.link} onPress={this.termsService}>{I18n.t('Terms_of_Service')}</Text>
|
||||
{I18n.t('and')}
|
||||
<Text style={styles.link} onPress={this.privacyPolicy}>{I18n.t('Privacy_Policy')}</Text>
|
||||
</Text>
|
||||
<Button
|
||||
title='Register'
|
||||
title={I18n.t('Register')}
|
||||
type='primary'
|
||||
onPress={this.submit}
|
||||
testID='register-view-submit'
|
||||
|
@ -176,8 +177,8 @@ export default class RegisterView extends LoggedView {
|
|||
<View>
|
||||
<TextInput
|
||||
inputRef={(e) => { this.username = e; }}
|
||||
label={this.props.Accounts_UsernamePlaceholder || 'Username'}
|
||||
placeholder={this.props.Accounts_UsernamePlaceholder || 'Username'}
|
||||
label={this.props.Accounts_UsernamePlaceholder || I18n.t('Username')}
|
||||
placeholder={this.props.Accounts_UsernamePlaceholder || I18n.t('Username')}
|
||||
returnKeyType='done'
|
||||
iconLeft='at'
|
||||
onChangeText={username => this.setState({ username })}
|
||||
|
@ -187,7 +188,7 @@ export default class RegisterView extends LoggedView {
|
|||
|
||||
<View style={styles.alignItemsFlexStart}>
|
||||
<Button
|
||||
title='Register'
|
||||
title={I18n.t('Register')}
|
||||
type='primary'
|
||||
onPress={this.usernameSubmit}
|
||||
testID='register-view-submit-username'
|
||||
|
@ -203,7 +204,7 @@ export default class RegisterView extends LoggedView {
|
|||
<ScrollView {...scrollPersistTaps} contentContainerStyle={styles.containerScrollView}>
|
||||
<SafeAreaView testID='register-view'>
|
||||
<CloseModalButton navigation={this.props.navigation} />
|
||||
<Text style={[styles.loginText, styles.loginTitle]}>Sign Up</Text>
|
||||
<Text style={[styles.loginText, styles.loginTitle]}>{I18n.t('Sign_Up')}</Text>
|
||||
{this._renderRegister()}
|
||||
{this._renderUsername()}
|
||||
{this.props.login.failure &&
|
||||
|
|
|
@ -17,6 +17,7 @@ import { leaveRoom } from '../../actions/room';
|
|||
import { setLoading } from '../../actions/selectedUsers';
|
||||
import log from '../../utils/log';
|
||||
import RoomTypeIcon from '../../containers/RoomTypeIcon';
|
||||
import I18n from '../../i18n';
|
||||
|
||||
const renderSeparator = () => <View style={styles.separator} />;
|
||||
const getRoomTitle = room => (room.t === 'd' ? <Text>{room.fname}</Text> : <Text><RoomTypeIcon type={room.t} /> {room.name}</Text>);
|
||||
|
@ -158,13 +159,13 @@ export default class RoomActionsView extends LoggedView {
|
|||
data: [
|
||||
{
|
||||
icon: 'ios-call-outline',
|
||||
name: 'Voice call',
|
||||
name: I18n.t('Voice_call'),
|
||||
disabled: true,
|
||||
testID: 'room-actions-voice'
|
||||
},
|
||||
{
|
||||
icon: 'ios-videocam-outline',
|
||||
name: 'Video call',
|
||||
name: I18n.t('Video_call'),
|
||||
disabled: true,
|
||||
testID: 'room-actions-video'
|
||||
}
|
||||
|
@ -174,55 +175,55 @@ export default class RoomActionsView extends LoggedView {
|
|||
data: [
|
||||
{
|
||||
icon: 'ios-attach',
|
||||
name: 'Files',
|
||||
name: I18n.t('Files'),
|
||||
route: 'RoomFiles',
|
||||
params: { rid },
|
||||
testID: 'room-actions-files'
|
||||
},
|
||||
{
|
||||
icon: 'ios-at-outline',
|
||||
name: 'Mentions',
|
||||
name: I18n.t('Mentions'),
|
||||
route: 'MentionedMessages',
|
||||
params: { rid },
|
||||
testID: 'room-actions-mentioned'
|
||||
},
|
||||
{
|
||||
icon: 'ios-star-outline',
|
||||
name: 'Starred',
|
||||
name: I18n.t('Starred'),
|
||||
route: 'StarredMessages',
|
||||
params: { rid },
|
||||
testID: 'room-actions-starred'
|
||||
},
|
||||
{
|
||||
icon: 'ios-search',
|
||||
name: 'Search',
|
||||
name: I18n.t('Search'),
|
||||
route: 'SearchMessages',
|
||||
params: { rid },
|
||||
testID: 'room-actions-search'
|
||||
},
|
||||
{
|
||||
icon: 'ios-share-outline',
|
||||
name: 'Share',
|
||||
name: I18n.t('Share'),
|
||||
disabled: true,
|
||||
testID: 'room-actions-share'
|
||||
},
|
||||
{
|
||||
icon: 'ios-pin',
|
||||
name: 'Pinned',
|
||||
name: I18n.t('Pinned'),
|
||||
route: 'PinnedMessages',
|
||||
params: { rid },
|
||||
testID: 'room-actions-pinned'
|
||||
},
|
||||
{
|
||||
icon: 'ios-code',
|
||||
name: 'Snippets',
|
||||
name: I18n.t('Snippets'),
|
||||
route: 'SnippetedMessages',
|
||||
params: { rid },
|
||||
testID: 'room-actions-snippeted'
|
||||
},
|
||||
{
|
||||
icon: `ios-notifications${ notifications ? '' : '-off' }-outline`,
|
||||
name: `${ notifications ? 'Enable' : 'Disable' } notifications`,
|
||||
name: I18n.t(`${ notifications ? 'Enable' : 'Disable' }_notifications`),
|
||||
event: () => this.toggleNotifications(),
|
||||
testID: 'room-actions-notifications'
|
||||
}
|
||||
|
@ -235,7 +236,7 @@ export default class RoomActionsView extends LoggedView {
|
|||
data: [
|
||||
{
|
||||
icon: 'block',
|
||||
name: `${ blocker ? 'Unblock' : 'Block' } user`,
|
||||
name: I18n.t(`${ blocker ? 'Unblock' : 'Block' }_user`),
|
||||
type: 'danger',
|
||||
event: () => this.toggleBlockUser(),
|
||||
testID: 'room-actions-block-user'
|
||||
|
@ -249,8 +250,10 @@ export default class RoomActionsView extends LoggedView {
|
|||
if (this.canViewMembers) {
|
||||
actions.push({
|
||||
icon: 'ios-people',
|
||||
name: 'Members',
|
||||
description: (onlineMembers.length === 1 ? `${ onlineMembers.length } member` : `${ onlineMembers.length } members`),
|
||||
name: I18n.t('Members'),
|
||||
description: (onlineMembers.length === 1 ?
|
||||
I18n.t('1_online_member') :
|
||||
I18n.t('N_online_members', { n: onlineMembers.length })),
|
||||
route: 'RoomMembers',
|
||||
params: { rid, members: onlineMembers },
|
||||
testID: 'room-actions-members'
|
||||
|
@ -260,7 +263,7 @@ export default class RoomActionsView extends LoggedView {
|
|||
if (this.canAddUser) {
|
||||
actions.push({
|
||||
icon: 'ios-person-add',
|
||||
name: 'Add user',
|
||||
name: I18n.t('Add_user'),
|
||||
route: 'SelectedUsers',
|
||||
params: {
|
||||
nextAction: async() => {
|
||||
|
@ -283,7 +286,7 @@ export default class RoomActionsView extends LoggedView {
|
|||
data: [
|
||||
{
|
||||
icon: 'block',
|
||||
name: 'Leave channel',
|
||||
name: I18n.t('Leave_channel'),
|
||||
type: 'danger',
|
||||
event: () => this.leaveChannel(),
|
||||
testID: 'room-actions-leave-channel'
|
||||
|
@ -308,15 +311,15 @@ export default class RoomActionsView extends LoggedView {
|
|||
leaveChannel = () => {
|
||||
const { room } = this.state;
|
||||
Alert.alert(
|
||||
'Are you sure?',
|
||||
`Are you sure you want to leave the room ${ getRoomTitle(room) }?`,
|
||||
I18n.t('Are_you_sure_question_mark'),
|
||||
I18n.t('Are_you_sure_you_want_to_leave_the_room', { room: room.t === 'd' ? room.fname : room.name }),
|
||||
[
|
||||
{
|
||||
text: 'Cancel',
|
||||
text: I18n.t('Cancel'),
|
||||
style: 'cancel'
|
||||
},
|
||||
{
|
||||
text: 'Yes, leave it!',
|
||||
text: I18n.t('Yes_action_it', { action: I18n.t('leave') }),
|
||||
style: 'destructive',
|
||||
onPress: () => this.props.leaveRoom(room.rid)
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import { openRoomFiles, closeRoomFiles } from '../../actions/roomFiles';
|
|||
import styles from './styles';
|
||||
import Message from '../../containers/message';
|
||||
import RCActivityIndicator from '../../containers/ActivityIndicator';
|
||||
import I18n from '../../i18n';
|
||||
|
||||
@connect(
|
||||
state => ({
|
||||
|
@ -74,7 +75,7 @@ export default class RoomFilesView extends LoggedView {
|
|||
|
||||
renderEmpty = () => (
|
||||
<View style={styles.listEmptyContainer} testID='room-files-view'>
|
||||
<Text>No files</Text>
|
||||
<Text>{I18n.t('No_files')}</Text>
|
||||
</View>
|
||||
)
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import Loading from '../../containers/Loading';
|
|||
import SwitchContainer from './SwitchContainer';
|
||||
import random from '../../utils/random';
|
||||
import log from '../../utils/log';
|
||||
import I18n from '../../i18n';
|
||||
|
||||
const PERMISSION_SET_READONLY = 'set-readonly';
|
||||
const PERMISSION_SET_REACT_WHEN_READONLY = 'set-react-when-readonly';
|
||||
|
@ -133,7 +134,7 @@ export default class RoomInfoEditView extends LoggedView {
|
|||
let error = false;
|
||||
|
||||
if (!this.formIsChanged()) {
|
||||
showErrorAlert('Nothing to save!');
|
||||
showErrorAlert(I18n.t('Nothing_to_save'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -189,24 +190,24 @@ export default class RoomInfoEditView extends LoggedView {
|
|||
await this.setState({ saving: false });
|
||||
setTimeout(() => {
|
||||
if (error) {
|
||||
showErrorAlert('There was an error while saving settings!');
|
||||
showErrorAlert(I18n.t('There_was_an_error_while_saving_settings'));
|
||||
} else {
|
||||
showToast('Settings succesfully changed!');
|
||||
showToast(I18n.t('Settings_succesfully_changed'));
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
|
||||
delete = () => {
|
||||
Alert.alert(
|
||||
'Are you sure?',
|
||||
'Deleting a room will delete all messages posted within the room. This cannot be undone.',
|
||||
I18n.t('Are_you_sure_question_mark'),
|
||||
I18n.t('Delete_Room_Warning'),
|
||||
[
|
||||
{
|
||||
text: 'Cancel',
|
||||
text: I18n.t('Cancel'),
|
||||
style: 'cancel'
|
||||
},
|
||||
{
|
||||
text: 'Yes, delete it!',
|
||||
text: I18n.t('Yes_action_it', { action: I18n.t('delete') }),
|
||||
style: 'destructive',
|
||||
onPress: () => this.props.eraseRoom(this.state.room.rid)
|
||||
}
|
||||
|
@ -217,17 +218,17 @@ export default class RoomInfoEditView extends LoggedView {
|
|||
|
||||
toggleArchive = () => {
|
||||
const { archived } = this.state.room;
|
||||
const action = `${ archived ? 'un' : '' }archive`;
|
||||
const action = I18n.t(`${ archived ? 'un' : '' }archive`);
|
||||
Alert.alert(
|
||||
'Are you sure?',
|
||||
`Do you really want to ${ action } this room?`,
|
||||
I18n.t('Are_you_sure_question_mark'),
|
||||
I18n.t('Do_you_really_want_to_key_this_room_question_mark', { key: action }),
|
||||
[
|
||||
{
|
||||
text: 'Cancel',
|
||||
text: I18n.t('Cancel'),
|
||||
style: 'cancel'
|
||||
},
|
||||
{
|
||||
text: `Yes, ${ action } it!`,
|
||||
text: I18n.t('Yes_action_it', { action }),
|
||||
style: 'destructive',
|
||||
onPress: () => {
|
||||
try {
|
||||
|
@ -268,7 +269,7 @@ export default class RoomInfoEditView extends LoggedView {
|
|||
<View style={sharedStyles.formContainer}>
|
||||
<RCTextInput
|
||||
inputRef={(e) => { this.name = e; }}
|
||||
label='Name'
|
||||
label={I18n.t('Name')}
|
||||
value={name}
|
||||
onChangeText={value => this.setState({ name: value })}
|
||||
onSubmitEditing={() => { this.description.focus(); }}
|
||||
|
@ -277,7 +278,7 @@ export default class RoomInfoEditView extends LoggedView {
|
|||
/>
|
||||
<RCTextInput
|
||||
inputRef={(e) => { this.description = e; }}
|
||||
label='Description'
|
||||
label={I18n.t('Description')}
|
||||
value={description}
|
||||
onChangeText={value => this.setState({ description: value })}
|
||||
onSubmitEditing={() => { this.topic.focus(); }}
|
||||
|
@ -285,7 +286,7 @@ export default class RoomInfoEditView extends LoggedView {
|
|||
/>
|
||||
<RCTextInput
|
||||
inputRef={(e) => { this.topic = e; }}
|
||||
label='Topic'
|
||||
label={I18n.t('Topic')}
|
||||
value={topic}
|
||||
onChangeText={value => this.setState({ topic: value })}
|
||||
onSubmitEditing={() => { this.announcement.focus(); }}
|
||||
|
@ -293,7 +294,7 @@ export default class RoomInfoEditView extends LoggedView {
|
|||
/>
|
||||
<RCTextInput
|
||||
inputRef={(e) => { this.announcement = e; }}
|
||||
label='Announcement'
|
||||
label={I18n.t('Announcement')}
|
||||
value={announcement}
|
||||
onChangeText={value => this.setState({ announcement: value })}
|
||||
onSubmitEditing={() => { this.joinCode.focus(); }}
|
||||
|
@ -301,7 +302,7 @@ export default class RoomInfoEditView extends LoggedView {
|
|||
/>
|
||||
<RCTextInput
|
||||
inputRef={(e) => { this.joinCode = e; }}
|
||||
label='Password'
|
||||
label={I18n.t('Password')}
|
||||
value={joinCode}
|
||||
onChangeText={value => this.setState({ joinCode: value })}
|
||||
onSubmitEditing={this.submit}
|
||||
|
@ -310,19 +311,19 @@ export default class RoomInfoEditView extends LoggedView {
|
|||
/>
|
||||
<SwitchContainer
|
||||
value={t}
|
||||
leftLabelPrimary='Public'
|
||||
leftLabelSecondary='Everyone can access this channel'
|
||||
rightLabelPrimary='Private'
|
||||
rightLabelSecondary='Just invited people can access this channel'
|
||||
leftLabelPrimary={I18n.t('Public')}
|
||||
leftLabelSecondary={I18n.t('Everyone_can_access_this_channel')}
|
||||
rightLabelPrimary={I18n.t('Private')}
|
||||
rightLabelSecondary={I18n.t('Just_invited_people_can_access_this_channel')}
|
||||
onValueChange={value => this.setState({ t: value })}
|
||||
testID='room-info-edit-view-t'
|
||||
/>
|
||||
<SwitchContainer
|
||||
value={ro}
|
||||
leftLabelPrimary='Colaborative'
|
||||
leftLabelSecondary='All users in the channel can write new messages'
|
||||
rightLabelPrimary='Read Only'
|
||||
rightLabelSecondary='Only authorized users can write new messages'
|
||||
leftLabelPrimary={I18n.t('Colaborative')}
|
||||
leftLabelSecondary={I18n.t('All_users_in_the_channel_can_write_new_messages')}
|
||||
rightLabelPrimary={I18n.t('Read_Only')}
|
||||
rightLabelSecondary={I18n.t('Only_authorized_users_can_write_new_messages')}
|
||||
onValueChange={value => this.setState({ ro: value })}
|
||||
disabled={!this.permissions[PERMISSION_SET_READONLY] || room.broadcast}
|
||||
testID='room-info-edit-view-ro'
|
||||
|
@ -330,10 +331,10 @@ export default class RoomInfoEditView extends LoggedView {
|
|||
{ro && !room.broadcast &&
|
||||
<SwitchContainer
|
||||
value={reactWhenReadOnly}
|
||||
leftLabelPrimary='No Reactions'
|
||||
leftLabelSecondary='Reactions are disabled'
|
||||
rightLabelPrimary='Allow Reactions'
|
||||
rightLabelSecondary='Reactions are enabled'
|
||||
leftLabelPrimary={I18n.t('No_Reactions')}
|
||||
leftLabelSecondary={I18n.t('Reactions_are_disabled')}
|
||||
rightLabelPrimary={I18n.t('Allow_Reactions')}
|
||||
rightLabelSecondary={I18n.t('Reactions_are_enabled')}
|
||||
onValueChange={value => this.setState({ reactWhenReadOnly: value })}
|
||||
disabled={!this.permissions[PERMISSION_SET_REACT_WHEN_READONLY]}
|
||||
testID='room-info-edit-view-react-when-ro'
|
||||
|
@ -341,7 +342,7 @@ export default class RoomInfoEditView extends LoggedView {
|
|||
}
|
||||
{room.broadcast &&
|
||||
[
|
||||
<Text style={styles.broadcast}>Broadcast channel</Text>,
|
||||
<Text style={styles.broadcast}>{I18n.t('Broadcast_Channel')}</Text>,
|
||||
<View style={styles.divider} />
|
||||
]
|
||||
}
|
||||
|
@ -351,7 +352,7 @@ export default class RoomInfoEditView extends LoggedView {
|
|||
disabled={!this.formIsChanged()}
|
||||
testID='room-info-edit-view-submit'
|
||||
>
|
||||
<Text style={sharedStyles.button} accessibilityTraits='button'>SAVE</Text>
|
||||
<Text style={sharedStyles.button} accessibilityTraits='button'>{I18n.t('SAVE')}</Text>
|
||||
</TouchableOpacity>
|
||||
<View style={{ flexDirection: 'row' }}>
|
||||
<TouchableOpacity
|
||||
|
@ -359,7 +360,7 @@ export default class RoomInfoEditView extends LoggedView {
|
|||
onPress={this.reset}
|
||||
testID='room-info-edit-view-reset'
|
||||
>
|
||||
<Text style={sharedStyles.button_inverted} accessibilityTraits='button'>RESET</Text>
|
||||
<Text style={sharedStyles.button_inverted} accessibilityTraits='button'>{I18n.t('RESET')}</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
style={[
|
||||
|
@ -373,7 +374,7 @@ export default class RoomInfoEditView extends LoggedView {
|
|||
testID='room-info-edit-view-archive'
|
||||
>
|
||||
<Text style={[sharedStyles.button_inverted, styles.colorDanger]} accessibilityTraits='button'>
|
||||
{ room.archived ? 'UNARCHIVE' : 'ARCHIVE' }
|
||||
{ room.archived ? I18n.t('UNARCHIVE') : I18n.t('ARCHIVE') }
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
@ -389,7 +390,7 @@ export default class RoomInfoEditView extends LoggedView {
|
|||
disabled={!this.hasDeletePermission()}
|
||||
testID='room-info-edit-view-delete'
|
||||
>
|
||||
<Text style={[sharedStyles.button_inverted, styles.colorDanger]} accessibilityTraits='button'>DELETE</Text>
|
||||
<Text style={[sharedStyles.button_inverted, styles.colorDanger]} accessibilityTraits='button'>{I18n.t('DELETE')}</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<Loading visible={this.state.saving} />
|
||||
|
|
|
@ -16,6 +16,7 @@ import Touch from '../../utils/touch';
|
|||
|
||||
import log from '../../utils/log';
|
||||
import RoomTypeIcon from '../../containers/RoomTypeIcon';
|
||||
import I18n from '../../i18n';
|
||||
|
||||
const PERMISSION_EDIT_ROOM = 'edit-room';
|
||||
|
||||
|
@ -56,7 +57,7 @@ export default class RoomInfoView extends LoggedView {
|
|||
onPress={() => navigation.navigate({ key: 'RoomInfoEdit', routeName: 'RoomInfoEdit', params: { rid: navigation.state.params.rid } })}
|
||||
underlayColor='#ffffff'
|
||||
activeOpacity={0.5}
|
||||
accessibilityLabel='edit'
|
||||
accessibilityLabel={I18n.t('edit')}
|
||||
accessibilityTraits='button'
|
||||
testID='room-info-view-edit-button'
|
||||
>
|
||||
|
@ -132,14 +133,14 @@ export default class RoomInfoView extends LoggedView {
|
|||
const [room] = this.rooms;
|
||||
this.setState({ room });
|
||||
}
|
||||
// TODO: translate
|
||||
|
||||
renderItem = (key, room) => (
|
||||
<View style={styles.item}>
|
||||
<Text style={styles.itemLabel}>{camelize(key)}</Text>
|
||||
<Text style={styles.itemLabel}>{I18n.t(camelize(key))}</Text>
|
||||
<Text
|
||||
style={[styles.itemContent, !room[key] && styles.itemContent__empty]}
|
||||
testID={`room-info-view-${ key }`}
|
||||
>{ room[key] ? room[key] : `No ${ key } provided.` }
|
||||
>{ room[key] ? room[key] : I18n.t(`No_${ key }_provided`) }
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
|
@ -147,7 +148,7 @@ export default class RoomInfoView extends LoggedView {
|
|||
renderRoles = () => (
|
||||
this.state.roles.length > 0 &&
|
||||
<View style={styles.item}>
|
||||
<Text style={styles.itemLabel}>Roles</Text>
|
||||
<Text style={styles.itemLabel}>{I18n.t('Roles')}</Text>
|
||||
<View style={styles.rolesContainer}>
|
||||
{this.state.roles.map(role => (
|
||||
<View style={styles.roleBadge} key={role}>
|
||||
|
@ -168,7 +169,7 @@ export default class RoomInfoView extends LoggedView {
|
|||
// TODO: translate
|
||||
return (
|
||||
<View style={styles.item}>
|
||||
<Text style={styles.itemLabel}>Timezone</Text>
|
||||
<Text style={styles.itemLabel}>{I18n.t('Timezone')}</Text>
|
||||
<Text style={styles.itemContent}>{moment().utcOffset(utcOffset).format(this.props.Message_TimeFormat)} (UTC { utcOffset })</Text>
|
||||
</View>
|
||||
);
|
||||
|
@ -189,11 +190,11 @@ export default class RoomInfoView extends LoggedView {
|
|||
|
||||
renderBroadcast = () => (
|
||||
<View style={styles.item}>
|
||||
<Text style={styles.itemLabel}>Broadcast Channel</Text>
|
||||
<Text style={styles.itemLabel}>{I18n.t('Broadcast_Channel')}</Text>
|
||||
<Text
|
||||
style={styles.itemContent}
|
||||
testID='room-info-view-broadcast'
|
||||
>Only authorized users can write new messages, but the other users will be able to reply
|
||||
>{I18n.t('Broadcast_channel_Description')}
|
||||
</Text>
|
||||
</View>
|
||||
)
|
||||
|
|
|
@ -14,6 +14,7 @@ import { goRoom } from '../../containers/routes/NavigationService';
|
|||
import database from '../../lib/realm';
|
||||
import { showToast } from '../../utils/info';
|
||||
import log from '../../utils/log';
|
||||
import I18n from '../../i18n';
|
||||
|
||||
@connect(state => ({
|
||||
user: state.login.user,
|
||||
|
@ -26,7 +27,7 @@ export default class MentionedMessagesView extends LoggedView {
|
|||
|
||||
static navigationOptions = ({ navigation }) => {
|
||||
const params = navigation.state.params || {};
|
||||
const label = params.allUsers ? 'All' : 'Online';
|
||||
const label = params.allUsers ? I18n.t('All') : I18n.t('Online');
|
||||
if (params.allUsers === undefined) {
|
||||
return;
|
||||
}
|
||||
|
@ -123,14 +124,14 @@ export default class MentionedMessagesView extends LoggedView {
|
|||
if (!this.permissions['mute-user']) {
|
||||
return;
|
||||
}
|
||||
this.actionSheetOptions = ['Cancel'];
|
||||
this.actionSheetOptions = [I18n.t('Cancel')];
|
||||
const { muted } = this.state.room;
|
||||
const userIsMuted = !!muted.find(m => m.value === user.username);
|
||||
user.muted = userIsMuted;
|
||||
if (userIsMuted) {
|
||||
this.actionSheetOptions.push('Unmute');
|
||||
this.actionSheetOptions.push(I18n.t('Unmute'));
|
||||
} else {
|
||||
this.actionSheetOptions.push('Mute');
|
||||
this.actionSheetOptions.push(I18n.t('Mute'));
|
||||
}
|
||||
this.setState({ userLongPressed: user });
|
||||
Vibration.vibrate(50);
|
||||
|
@ -141,7 +142,7 @@ export default class MentionedMessagesView extends LoggedView {
|
|||
const { rid, userLongPressed } = this.state;
|
||||
try {
|
||||
await RocketChat.toggleMuteUserInRoom(rid, userLongPressed.username, !userLongPressed.muted);
|
||||
showToast(`User has been ${ userLongPressed.muted ? 'unmuted' : 'muted' }!`);
|
||||
showToast(I18n.t('User_has_been_key', { key: userLongPressed.muted ? I18n.t('unmuted') : I18n.t('muted') }));
|
||||
} catch (e) {
|
||||
log('handleMute', e);
|
||||
}
|
||||
|
@ -164,7 +165,7 @@ export default class MentionedMessagesView extends LoggedView {
|
|||
style={styles.searchBox}
|
||||
onChangeText={text => this.onSearchChangeText(text)}
|
||||
returnKeyType='search'
|
||||
placeholder='Search'
|
||||
placeholder={I18n.t('Search')}
|
||||
clearButtonMode='while-editing'
|
||||
blurOnSubmit
|
||||
autoCorrect={false}
|
||||
|
@ -209,7 +210,7 @@ export default class MentionedMessagesView extends LoggedView {
|
|||
<ActionSheet
|
||||
key='room-members-actionsheet'
|
||||
ref={o => this.ActionSheet = o}
|
||||
title='Actions'
|
||||
title={I18n.t('Actions')}
|
||||
options={this.actionSheetOptions}
|
||||
cancelButtonIndex={this.CANCEL_INDEX}
|
||||
onPress={this.handleActionPress}
|
||||
|
|
|
@ -11,28 +11,28 @@ import Avatar from '../../../containers/Avatar';
|
|||
import { STATUS_COLORS } from '../../../constants/colors';
|
||||
import styles from './styles';
|
||||
import { closeRoom } from '../../../actions/room';
|
||||
|
||||
import log from '../../../utils/log';
|
||||
import RoomTypeIcon from '../../../containers/RoomTypeIcon';
|
||||
import I18n from '../../../i18n';
|
||||
|
||||
const title = (offline, connecting, authenticating, logged) => {
|
||||
if (offline) {
|
||||
return 'You are offline...';
|
||||
return `${ I18n.t('You_are_offline') }...`;
|
||||
}
|
||||
|
||||
if (connecting) {
|
||||
return 'Connecting...';
|
||||
return `${ I18n.t('Connecting') }...`;
|
||||
}
|
||||
|
||||
if (authenticating) {
|
||||
return 'Authenticating...';
|
||||
return `${ I18n.t('Authenticating') }...`;
|
||||
}
|
||||
|
||||
if (logged) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return 'Not logged...';
|
||||
return `${ I18n.t('Not_logged') }...`;
|
||||
};
|
||||
|
||||
@connect(state => ({
|
||||
|
@ -87,7 +87,7 @@ export default class RoomHeaderView extends React.PureComponent {
|
|||
|
||||
getUserStatusLabel() {
|
||||
const status = this.getUserStatus();
|
||||
return status.charAt(0).toUpperCase() + status.slice(1);
|
||||
return I18n.t(status.charAt(0).toUpperCase() + status.slice(1));
|
||||
}
|
||||
|
||||
updateState = () => {
|
||||
|
@ -104,7 +104,7 @@ export default class RoomHeaderView extends React.PureComponent {
|
|||
requestAnimationFrame(() => this.props.close());
|
||||
}}
|
||||
tintColor='#292E35'
|
||||
title='Back'
|
||||
title={I18n.t('Back')}
|
||||
titleStyle={{ display: 'none' }}
|
||||
/>);
|
||||
|
||||
|
@ -124,7 +124,7 @@ export default class RoomHeaderView extends React.PureComponent {
|
|||
|
||||
let t = '';
|
||||
if (!title(offline, connecting, authenticating, logged) && loading) {
|
||||
t = 'Loading messages...';
|
||||
t = I18n.t('Loading_messages_ellipsis');
|
||||
} else if (this.isDirect()) {
|
||||
t = this.getUserStatusLabel();
|
||||
} else {
|
||||
|
@ -177,7 +177,7 @@ export default class RoomHeaderView extends React.PureComponent {
|
|||
log('toggleFavorite', e);
|
||||
}
|
||||
}}
|
||||
accessibilityLabel='Star room'
|
||||
accessibilityLabel={I18n.t('Star_room')}
|
||||
accessibilityTraits='button'
|
||||
testID='room-view-header-star'
|
||||
>
|
||||
|
@ -191,7 +191,7 @@ export default class RoomHeaderView extends React.PureComponent {
|
|||
<TouchableOpacity
|
||||
style={styles.headerButton}
|
||||
onPress={() => this.props.navigation.navigate({ key: 'RoomActions', routeName: 'RoomActions', params: { rid: this.state.room.rid } })}
|
||||
accessibilityLabel='Room actions'
|
||||
accessibilityLabel={I18n.t('Room_actions')}
|
||||
accessibilityTraits='button'
|
||||
testID='room-view-header-actions'
|
||||
>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import React from 'react';
|
||||
import { View, StyleSheet, Text, LayoutAnimation } from 'react-native';
|
||||
import I18n from '../../i18n';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
firstUnread: {
|
||||
|
@ -30,7 +31,7 @@ export default class UnreadSeparator extends React.PureComponent {
|
|||
return (
|
||||
<View style={styles.firstUnread}>
|
||||
<View style={styles.firstUnreadLine} />
|
||||
<Text style={styles.firstUnreadBadge}>unread messages</Text>
|
||||
<Text style={styles.firstUnreadBadge}>{I18n.t('unread_messages')}</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Text, View } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
import styles from './styles';
|
||||
|
||||
@connect(state => ({
|
||||
loading: state.messages.isFetching
|
||||
}), null)
|
||||
export default class Banner extends React.PureComponent {
|
||||
static propTypes = {
|
||||
loading: PropTypes.bool
|
||||
};
|
||||
|
||||
render() {
|
||||
return (this.props.loading ? (
|
||||
<View style={styles.bannerContainer}>
|
||||
<Text style={styles.bannerText}>Loading new messages...</Text>
|
||||
</View>
|
||||
) : null);
|
||||
}
|
||||
}
|
|
@ -2,12 +2,12 @@ import React from 'react';
|
|||
import PropTypes from 'prop-types';
|
||||
import { Text, View, Button } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
// import { bindActionCreators } from 'redux';
|
||||
import equal from 'deep-equal';
|
||||
|
||||
import LoggedView from '../View';
|
||||
import { List } from './ListView';
|
||||
import * as actions from '../../actions';
|
||||
// import * as actions from '../../actions';
|
||||
import { openRoom, setLastOpen } from '../../actions/room';
|
||||
import { editCancel, toggleReactionPicker, actionsShow } from '../../actions/messages';
|
||||
import database from '../../lib/realm';
|
||||
|
@ -21,17 +21,18 @@ import RoomsHeader from './Header';
|
|||
import ReactionPicker from './ReactionPicker';
|
||||
import styles from './styles';
|
||||
import log from '../../utils/log';
|
||||
import I18n from '../../i18n';
|
||||
|
||||
@connect(
|
||||
state => ({
|
||||
Site_Url: state.settings.Site_Url || state.server ? state.server.server : '',
|
||||
Message_TimeFormat: state.settings.Message_TimeFormat,
|
||||
// Site_Url: state.settings.Site_Url || state.server ? state.server.server : '',
|
||||
// Message_TimeFormat: state.settings.Message_TimeFormat,
|
||||
loading: state.messages.isFetching,
|
||||
user: state.login.user,
|
||||
actionMessage: state.messages.actionMessage
|
||||
}),
|
||||
dispatch => ({
|
||||
actions: bindActionCreators(actions, dispatch),
|
||||
// actions: bindActionCreators(actions, dispatch),
|
||||
openRoom: room => dispatch(openRoom(room)),
|
||||
editCancel: () => dispatch(editCancel()),
|
||||
setLastOpen: date => dispatch(setLastOpen(date)),
|
||||
|
@ -48,8 +49,8 @@ export default class RoomView extends LoggedView {
|
|||
editCancel: PropTypes.func,
|
||||
rid: PropTypes.string,
|
||||
name: PropTypes.string,
|
||||
Site_Url: PropTypes.string,
|
||||
Message_TimeFormat: PropTypes.string,
|
||||
// Site_Url: PropTypes.string,
|
||||
// Message_TimeFormat: PropTypes.string,
|
||||
loading: PropTypes.bool,
|
||||
actionMessage: PropTypes.object,
|
||||
toggleReactionPicker: PropTypes.func.isRequired,
|
||||
|
@ -191,7 +192,7 @@ export default class RoomView extends LoggedView {
|
|||
if (!this.state.joined) {
|
||||
return (
|
||||
<View>
|
||||
<Text>You are in preview mode.</Text>
|
||||
<Text>{I18n.t('You_are_in_preview_mode')}</Text>
|
||||
<Button title='Join' onPress={this.joinRoom} />
|
||||
</View>
|
||||
);
|
||||
|
@ -199,14 +200,14 @@ export default class RoomView extends LoggedView {
|
|||
if (this.state.room.archived || this.isReadOnly()) {
|
||||
return (
|
||||
<View style={styles.readOnly}>
|
||||
<Text>This room is read only</Text>
|
||||
<Text>{I18n.t('This_room_is_read_only')}</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
if (this.isBlocked()) {
|
||||
return (
|
||||
<View style={styles.blockedOrBlocker}>
|
||||
<Text>This room is blocked</Text>
|
||||
<Text>{I18n.t('This_room_is_blocked')}</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
@ -215,9 +216,9 @@ export default class RoomView extends LoggedView {
|
|||
|
||||
renderHeader = () => {
|
||||
if (this.state.end) {
|
||||
return <Text style={styles.loadingMore}>Start of conversation</Text>;
|
||||
return <Text style={styles.loadingMore}>{I18n.t('Start_of_conversation')}</Text>;
|
||||
}
|
||||
return <Text style={styles.loadingMore}>Loading more messages...</Text>;
|
||||
return <Text style={styles.loadingMore}>{I18n.t('Loading_messages_ellipsis')}</Text>;
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
|
|
|
@ -14,25 +14,26 @@ import { STATUS_COLORS } from '../../../constants/colors';
|
|||
import { setSearch } from '../../../actions/rooms';
|
||||
import styles from './styles';
|
||||
import log from '../../../utils/log';
|
||||
import I18n from '../../../i18n';
|
||||
|
||||
const title = (offline, connecting, authenticating, logged) => {
|
||||
if (offline) {
|
||||
return 'offline...';
|
||||
return `${ I18n.t('Offline') }...`;
|
||||
}
|
||||
|
||||
if (connecting) {
|
||||
return 'Connecting...';
|
||||
return `${ I18n.t('Connecting') }...`;
|
||||
}
|
||||
|
||||
if (authenticating) {
|
||||
return 'Authenticating...';
|
||||
return `${ I18n.t('Authenticating') }...`;
|
||||
}
|
||||
|
||||
if (logged) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return 'Not logged...';
|
||||
return `${ I18n.t('Not_logged') }...`;
|
||||
};
|
||||
|
||||
@connect(state => ({
|
||||
|
@ -96,7 +97,7 @@ export default class RoomsListHeaderView extends React.PureComponent {
|
|||
|
||||
getUserStatusLabel() {
|
||||
const status = this.getUserStatus();
|
||||
return status.charAt(0).toUpperCase() + status.slice(1);
|
||||
return I18n.t(status.charAt(0).toUpperCase() + status.slice(1));
|
||||
}
|
||||
|
||||
showModal() {
|
||||
|
@ -124,7 +125,7 @@ export default class RoomsListHeaderView extends React.PureComponent {
|
|||
<View
|
||||
style={styles.left}
|
||||
accessible
|
||||
accessibilityLabel={`Connected to ${ this.props.baseUrl }. Tap to view servers list.`}
|
||||
accessibilityLabel={`${ I18n.t('Connected_to') } ${ this.props.baseUrl }. ${ I18n.t('Tap_to_view_servers_list') }.`}
|
||||
accessibilityTraits='button'
|
||||
testID='rooms-list-view-sidebar'
|
||||
>
|
||||
|
@ -156,7 +157,7 @@ export default class RoomsListHeaderView extends React.PureComponent {
|
|||
|
||||
const t = title(offline, connecting, authenticating, logged);
|
||||
|
||||
const accessibilityLabel = `${ user.username }, ${ this.getUserStatusLabel() }, tap to change status`;
|
||||
const accessibilityLabel = `${ user.username }, ${ this.getUserStatusLabel() }, ${ I18n.t('tap_to_change_status') }`;
|
||||
return (
|
||||
<TouchableOpacity
|
||||
style={styles.titleContainer}
|
||||
|
@ -190,7 +191,7 @@ export default class RoomsListHeaderView extends React.PureComponent {
|
|||
<TouchableOpacity
|
||||
style={styles.headerButton}
|
||||
onPress={() => this.onPressSearchButton()}
|
||||
accessibilityLabel='Search'
|
||||
accessibilityLabel={I18n.t('Search')}
|
||||
accessibilityTraits='button'
|
||||
>
|
||||
<Icon
|
||||
|
@ -204,7 +205,7 @@ export default class RoomsListHeaderView extends React.PureComponent {
|
|||
<TouchableOpacity
|
||||
style={styles.headerButton}
|
||||
onPress={() => this.createChannel()}
|
||||
accessibilityLabel='Create channel'
|
||||
accessibilityLabel={I18n.t('Create_Channel')}
|
||||
accessibilityTraits='button'
|
||||
testID='rooms-list-view-create-channel'
|
||||
>
|
||||
|
@ -223,6 +224,7 @@ export default class RoomsListHeaderView extends React.PureComponent {
|
|||
renderModalButton = (status, text) => {
|
||||
const statusStyle = [styles.status, { marginRight: 10, backgroundColor: STATUS_COLORS[status] }];
|
||||
const textStyle = { flex: 1, fontWeight: this.props.user.status === status ? 'bold' : 'normal' };
|
||||
const label = text || status;
|
||||
return (
|
||||
<TouchableOpacity
|
||||
style={styles.modalButton}
|
||||
|
@ -231,7 +233,7 @@ export default class RoomsListHeaderView extends React.PureComponent {
|
|||
>
|
||||
<View style={statusStyle} />
|
||||
<Text style={textStyle}>
|
||||
{text || status.charAt(0).toUpperCase() + status.slice(1)}
|
||||
{I18n.t(label.charAt(0).toUpperCase() + label.slice(1))}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
|
@ -252,7 +254,7 @@ export default class RoomsListHeaderView extends React.PureComponent {
|
|||
style={styles.inputSearch}
|
||||
onChangeText={text => this.onSearchChangeText(text)}
|
||||
returnKeyType='search'
|
||||
placeholder='Search'
|
||||
placeholder={I18n.t('Search')}
|
||||
clearButtonMode='while-editing'
|
||||
blurOnSubmit
|
||||
autoCorrect={false}
|
||||
|
@ -281,7 +283,7 @@ export default class RoomsListHeaderView extends React.PureComponent {
|
|||
{this.renderModalButton('online')}
|
||||
{this.renderModalButton('busy')}
|
||||
{this.renderModalButton('away')}
|
||||
{this.renderModalButton('offline', 'Invisible')}
|
||||
{this.renderModalButton('offline', 'invisible')}
|
||||
</View>
|
||||
</Modal>
|
||||
</View>
|
||||
|
|
|
@ -14,6 +14,7 @@ import styles from './styles';
|
|||
import debounce from '../../utils/debounce';
|
||||
import LoggedView from '../View';
|
||||
import log from '../../utils/log';
|
||||
import I18n from '../../i18n';
|
||||
|
||||
@connect(state => ({
|
||||
user: state.login.user,
|
||||
|
@ -166,7 +167,7 @@ export default class RoomsListView extends LoggedView {
|
|||
style={styles.searchBox}
|
||||
onChangeText={text => this.onSearchChangeText(text)}
|
||||
returnKeyType='search'
|
||||
placeholder='Search'
|
||||
placeholder={I18n.t('Search')}
|
||||
clearButtonMode='while-editing'
|
||||
blurOnSubmit
|
||||
autoCorrect={false}
|
||||
|
@ -213,7 +214,7 @@ export default class RoomsListView extends LoggedView {
|
|||
|
||||
renderCreateButtons = () => (
|
||||
<ActionButton buttonColor='rgba(231,76,60,1)'>
|
||||
<ActionButton.Item buttonColor='#9b59b6' title='Create Channel' onPress={() => { this.createChannel(); }} >
|
||||
<ActionButton.Item buttonColor='#9b59b6' title={I18n.t('Create_Channel')} onPress={() => { this.createChannel(); }} >
|
||||
<Icon name='md-chatbubbles' style={styles.actionButtonIcon} />
|
||||
</ActionButton.Item>
|
||||
</ActionButton>
|
||||
|
|
|
@ -14,6 +14,7 @@ import buildMessage from '../../lib/methods/helpers/buildMessage';
|
|||
import Message from '../../containers/message';
|
||||
import scrollPersistTaps from '../../utils/scrollPersistTaps';
|
||||
import log from '../../utils/log';
|
||||
import I18n from '../../i18n';
|
||||
|
||||
@connect(state => ({
|
||||
user: state.login.user,
|
||||
|
@ -114,12 +115,12 @@ export default class SearchMessagesView extends LoggedView {
|
|||
<View style={styles.searchContainer}>
|
||||
<RCTextInput
|
||||
inputRef={(e) => { this.name = e; }}
|
||||
label='Search'
|
||||
label={I18n.t('Search')}
|
||||
onChangeText={this.onChangeSearch}
|
||||
placeholder='Search Messages'
|
||||
placeholder={I18n.t('Search_Messages')}
|
||||
testID='search-message-view-input'
|
||||
/>
|
||||
<Markdown msg='You can search using RegExp. e.g. `/^text$/i`' />
|
||||
<Markdown msg={I18n.t('You_can_search_using_RegExp_eg')} />
|
||||
<View style={styles.divider} />
|
||||
</View>
|
||||
<FlatList
|
||||
|
|
|
@ -12,6 +12,7 @@ import Avatar from '../containers/Avatar';
|
|||
import Loading from '../containers/Loading';
|
||||
import debounce from '../utils/debounce';
|
||||
import LoggedView from './View';
|
||||
import I18n from '../i18n';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
|
@ -101,7 +102,7 @@ export default class SelectedUsersView extends LoggedView {
|
|||
justifyContent: 'center'
|
||||
}}
|
||||
onPress={() => params.nextAction()}
|
||||
accessibilityLabel='Submit'
|
||||
accessibilityLabel={I18n.t('Submit')}
|
||||
accessibilityTraits='button'
|
||||
testID='selected-users-view-submit'
|
||||
>
|
||||
|
@ -227,7 +228,7 @@ export default class SelectedUsersView extends LoggedView {
|
|||
style={styles.searchBox}
|
||||
onChangeText={text => this.onSearchChangeText(text)}
|
||||
returnKeyType='search'
|
||||
placeholder='Search'
|
||||
placeholder={I18n.t('Search')}
|
||||
clearButtonMode='while-editing'
|
||||
blurOnSubmit
|
||||
testID='select-users-view-search'
|
||||
|
|
|
@ -8,6 +8,7 @@ import { openSnippetedMessages, closeSnippetedMessages } from '../../actions/sni
|
|||
import styles from './styles';
|
||||
import Message from '../../containers/message';
|
||||
import RCActivityIndicator from '../../containers/ActivityIndicator';
|
||||
import I18n from '../../i18n';
|
||||
|
||||
@connect(
|
||||
state => ({
|
||||
|
@ -74,7 +75,7 @@ export default class SnippetedMessagesView extends LoggedView {
|
|||
|
||||
renderEmpty = () => (
|
||||
<View style={styles.listEmptyContainer} testID='snippeted-messages-view'>
|
||||
<Text>No snippeted messages</Text>
|
||||
<Text>{I18n.t('No_snippeted_messages')}</Text>
|
||||
</View>
|
||||
)
|
||||
|
||||
|
|
|
@ -10,10 +10,11 @@ import styles from './styles';
|
|||
import Message from '../../containers/message';
|
||||
import { toggleStarRequest } from '../../actions/messages';
|
||||
import RCActivityIndicator from '../../containers/ActivityIndicator';
|
||||
import I18n from '../../i18n';
|
||||
|
||||
const STAR_INDEX = 0;
|
||||
const CANCEL_INDEX = 1;
|
||||
const options = ['Unstar', 'Cancel'];
|
||||
const options = [I18n.t('Unstar'), I18n.t('Cancel')];
|
||||
|
||||
@connect(
|
||||
state => ({
|
||||
|
@ -98,7 +99,7 @@ export default class StarredMessagesView extends LoggedView {
|
|||
|
||||
renderEmpty = () => (
|
||||
<View style={styles.listEmptyContainer} testID='starred-messages-view'>
|
||||
<Text>No starred messages</Text>
|
||||
<Text>{I18n.t('No_starred_messages')}</Text>
|
||||
</View>
|
||||
)
|
||||
|
||||
|
@ -138,7 +139,7 @@ export default class StarredMessagesView extends LoggedView {
|
|||
<ActionSheet
|
||||
key='starred-messages-view-action-sheet'
|
||||
ref={o => this.actionSheet = o}
|
||||
title='Actions'
|
||||
title={I18n.t('Actions')}
|
||||
options={options}
|
||||
cancelButtonIndex={CANCEL_INDEX}
|
||||
onPress={this.handleActionPress}
|
||||
|
|
|
@ -3,15 +3,11 @@ import PropTypes from 'prop-types';
|
|||
import { WebView } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
class TermsServiceView extends React.Component {
|
||||
class TermsServiceView extends React.PureComponent {
|
||||
static propTypes = {
|
||||
termsService: PropTypes.string
|
||||
}
|
||||
|
||||
static navigationOptions = () => ({
|
||||
title: 'Terms of service'
|
||||
});
|
||||
|
||||
render() {
|
||||
return (
|
||||
<WebView source={{ html: this.props.termsService }} />
|
||||
|
|
|
@ -178,16 +178,16 @@ describe('Room screen', () => {
|
|||
describe('Message', async() => {
|
||||
it('should show message actions', async() => {
|
||||
await element(by.text(`${ data.random }message`)).longPress();
|
||||
await waitFor(element(by.text('Messages actions'))).toBeVisible().withTimeout(5000);
|
||||
await expect(element(by.text('Messages actions'))).toBeVisible();
|
||||
await waitFor(element(by.text('Message actions'))).toBeVisible().withTimeout(5000);
|
||||
await expect(element(by.text('Message actions'))).toBeVisible();
|
||||
await element(by.text('Cancel')).tap();
|
||||
await waitFor(element(by.text('Cancel'))).toBeNotVisible().withTimeout(2000);
|
||||
});
|
||||
|
||||
it('should copy permalink', async() => {
|
||||
await element(by.text(`${ data.random }message`)).longPress();
|
||||
await waitFor(element(by.text('Messages actions'))).toBeVisible().withTimeout(5000);
|
||||
await expect(element(by.text('Messages actions'))).toBeVisible();
|
||||
await waitFor(element(by.text('Message actions'))).toBeVisible().withTimeout(5000);
|
||||
await expect(element(by.text('Message actions'))).toBeVisible();
|
||||
await element(by.text('Copy Permalink')).tap();
|
||||
await expect(element(by.text('Permalink copied to clipboard!'))).toBeVisible();
|
||||
await waitFor(element(by.text('Permalink copied to clipboard!'))).toBeNotVisible().withTimeout(5000);
|
||||
|
@ -197,8 +197,8 @@ describe('Room screen', () => {
|
|||
|
||||
it('should copy message', async() => {
|
||||
await element(by.text(`${ data.random }message`)).longPress();
|
||||
await waitFor(element(by.text('Messages actions'))).toBeVisible().withTimeout(5000);
|
||||
await expect(element(by.text('Messages actions'))).toBeVisible();
|
||||
await waitFor(element(by.text('Message actions'))).toBeVisible().withTimeout(5000);
|
||||
await expect(element(by.text('Message actions'))).toBeVisible();
|
||||
await element(by.text('Copy Message')).tap();
|
||||
await expect(element(by.text('Copied to clipboard!'))).toBeVisible();
|
||||
await waitFor(element(by.text('Copied to clipboard!'))).toBeNotVisible().withTimeout(5000);
|
||||
|
@ -207,10 +207,10 @@ describe('Room screen', () => {
|
|||
|
||||
it('should star message', async() => {
|
||||
await element(by.text(`${ data.random }message`)).longPress();
|
||||
await waitFor(element(by.text('Messages actions'))).toBeVisible().withTimeout(5000);
|
||||
await expect(element(by.text('Messages actions'))).toBeVisible();
|
||||
await waitFor(element(by.text('Message actions'))).toBeVisible().withTimeout(5000);
|
||||
await expect(element(by.text('Message actions'))).toBeVisible();
|
||||
await element(by.text('Star')).tap();
|
||||
await waitFor(element(by.text('Messages actions'))).toBeNotVisible().withTimeout(5000);
|
||||
await waitFor(element(by.text('Message actions'))).toBeNotVisible().withTimeout(5000);
|
||||
await element(by.text(`${ data.random }message`)).longPress();
|
||||
await waitFor(element(by.text('Unstar'))).toBeVisible().withTimeout(2000);
|
||||
await expect(element(by.text('Unstar'))).toBeVisible();
|
||||
|
@ -220,8 +220,8 @@ describe('Room screen', () => {
|
|||
|
||||
it('should react to message', async() => {
|
||||
await element(by.text(`${ data.random }message`)).longPress();
|
||||
await waitFor(element(by.text('Messages actions'))).toBeVisible().withTimeout(5000);
|
||||
await expect(element(by.text('Messages actions'))).toBeVisible();
|
||||
await waitFor(element(by.text('Message actions'))).toBeVisible().withTimeout(5000);
|
||||
await expect(element(by.text('Message actions'))).toBeVisible();
|
||||
await element(by.text('Add Reaction')).tap();
|
||||
await waitFor(element(by.id('reaction-picker'))).toBeVisible().withTimeout(2000);
|
||||
await expect(element(by.id('reaction-picker'))).toBeVisible();
|
||||
|
@ -254,8 +254,8 @@ describe('Room screen', () => {
|
|||
it('should reply message', async() => {
|
||||
await mockMessage('reply');
|
||||
await element(by.text(`${ data.random }reply`)).longPress();
|
||||
await waitFor(element(by.text('Messages actions'))).toBeVisible().withTimeout(5000);
|
||||
await expect(element(by.text('Messages actions'))).toBeVisible();
|
||||
await waitFor(element(by.text('Message actions'))).toBeVisible().withTimeout(5000);
|
||||
await expect(element(by.text('Message actions'))).toBeVisible();
|
||||
await element(by.text('Reply')).tap();
|
||||
await element(by.id('messagebox-input')).typeText('replied');
|
||||
await element(by.id('messagebox-send-message')).tap();
|
||||
|
@ -265,8 +265,8 @@ describe('Room screen', () => {
|
|||
it('should edit message', async() => {
|
||||
await mockMessage('edit');
|
||||
await element(by.text(`${ data.random }edit`)).longPress();
|
||||
await waitFor(element(by.text('Messages actions'))).toBeVisible().withTimeout(5000);
|
||||
await expect(element(by.text('Messages actions'))).toBeVisible();
|
||||
await waitFor(element(by.text('Message actions'))).toBeVisible().withTimeout(5000);
|
||||
await expect(element(by.text('Message actions'))).toBeVisible();
|
||||
await element(by.text('Edit')).tap();
|
||||
await element(by.id('messagebox-input')).typeText('ed');
|
||||
await element(by.id('messagebox-send-message')).tap();
|
||||
|
@ -277,8 +277,8 @@ describe('Room screen', () => {
|
|||
it('should quote message', async() => {
|
||||
await mockMessage('quote');
|
||||
await element(by.text(`${ data.random }quote`)).longPress();
|
||||
await waitFor(element(by.text('Messages actions'))).toBeVisible().withTimeout(5000);
|
||||
await expect(element(by.text('Messages actions'))).toBeVisible();
|
||||
await waitFor(element(by.text('Message actions'))).toBeVisible().withTimeout(5000);
|
||||
await expect(element(by.text('Message actions'))).toBeVisible();
|
||||
await element(by.text('Quote')).tap();
|
||||
await element(by.id('messagebox-input')).typeText(`${ data.random }quoted`);
|
||||
await element(by.id('messagebox-send-message')).tap();
|
||||
|
@ -287,10 +287,10 @@ describe('Room screen', () => {
|
|||
|
||||
it('should pin message', async() => {
|
||||
await element(by.text(`${ data.random }edited`)).longPress();
|
||||
await waitFor(element(by.text('Messages actions'))).toBeVisible().withTimeout(5000);
|
||||
await expect(element(by.text('Messages actions'))).toBeVisible();
|
||||
await waitFor(element(by.text('Message actions'))).toBeVisible().withTimeout(5000);
|
||||
await expect(element(by.text('Message actions'))).toBeVisible();
|
||||
await element(by.text('Pin')).tap();
|
||||
await waitFor(element(by.text('Messages actions'))).toBeNotVisible().withTimeout(5000);
|
||||
await waitFor(element(by.text('Message actions'))).toBeNotVisible().withTimeout(5000);
|
||||
await waitFor(element(by.text(`${ data.random }edited`)).atIndex(1)).toBeVisible().withTimeout(60000);
|
||||
await element(by.text(`${ data.random }edited`)).atIndex(0).longPress();
|
||||
await waitFor(element(by.text('Unpin'))).toBeVisible().withTimeout(2000);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; };
|
||||
00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; };
|
||||
|
@ -12,6 +13,7 @@
|
|||
00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */; };
|
||||
00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; };
|
||||
00E356F31AD99517003FC87E /* RocketChatRNTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* RocketChatRNTests.m */; };
|
||||
09CB5909C1E64707832358CE /* libRNI18n-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C01CD6D4653143EEB5100C3A /* libRNI18n-tvOS.a */; };
|
||||
0C6E2DE448364EA896869ADF /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = B37C79D9BD0742CE936B6982 /* libc++.tbd */; };
|
||||
0DC38A29B0E54AF4AF96CB95 /* MaterialCommunityIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 2EADB1731B5E47D093292B59 /* MaterialCommunityIcons.ttf */; };
|
||||
0F026E58B8A6427D9A204D89 /* libSplashScreen.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B2607FA180F14E6584301101 /* libSplashScreen.a */; };
|
||||
|
@ -65,12 +67,13 @@
|
|||
B8C682AD1FD8511E003A12C8 /* Ionicons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 1B0746E708284151B8AD1198 /* Ionicons.ttf */; };
|
||||
B8C682AE1FD8511F003A12C8 /* Ionicons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 1B0746E708284151B8AD1198 /* Ionicons.ttf */; };
|
||||
B8E79AF41F3CD167005B464F /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB61A68108700A75B9A /* Info.plist */; };
|
||||
BAB7DC22804246F3923A1833 /* libFastImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD2E2837F110483CA29EE0D4 /* libFastImage.a */; };
|
||||
BED2B77AA660460E8BC9F8E0 /* libRNFetchBlob.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6533FB90166345D29F1B91C0 /* libRNFetchBlob.a */; };
|
||||
C758F0BD5C3244E2BA073E61 /* libRNImagePicker.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B696712EE2345A59F007A88 /* libRNImagePicker.a */; };
|
||||
CBD0E0A35B174C4DBFED3B31 /* Zocial.ttf in Resources */ = {isa = PBXBuildFile; fileRef = E528DE3A405E43B4A37ABA68 /* Zocial.ttf */; };
|
||||
D6408D9E4A864FF6BA986857 /* SimpleLineIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 8A2DD67ADD954AD9873F45FC /* SimpleLineIcons.ttf */; };
|
||||
EF736EF520A64AE8820E684A /* libRealmReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DF26CC845883492D8AC8869B /* libRealmReact.a */; };
|
||||
BAB7DC22804246F3923A1833 /* libFastImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD2E2837F110483CA29EE0D4 /* libFastImage.a */; };
|
||||
F5BF54DC78E1411B8343933B /* libRNI18n.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 921481B47B50490CA761932E /* libRNI18n.a */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
|
@ -326,6 +329,27 @@
|
|||
remoteGlobalIDString = 39DF4FE71E00394E00F5B4B2;
|
||||
remoteInfo = RCTCustomInputController;
|
||||
};
|
||||
7A770EC120BECDC7001AD51A /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 1845C223DA364898A8400573 /* FastImage.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = A287971D1DE0C0A60081BDFA;
|
||||
remoteInfo = FastImage;
|
||||
};
|
||||
7A770EC520BECDC7001AD51A /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 22D3971EAF2E4660B4FAB3DD /* RNI18n.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 134814201AA4EA6300B7C361;
|
||||
remoteInfo = RNI18n;
|
||||
};
|
||||
7A770EC720BECDC7001AD51A /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 22D3971EAF2E4660B4FAB3DD /* RNI18n.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 6476C4051EEAA69700B10F51;
|
||||
remoteInfo = "RNI18n-tvOS";
|
||||
};
|
||||
7A7F5C981FCC982500024129 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = AD0379F2BCE84C968538CDAF /* RCTVideo.xcodeproj */;
|
||||
|
@ -490,10 +514,12 @@
|
|||
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = RocketChatRN/Info.plist; sourceTree = "<group>"; };
|
||||
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = RocketChatRN/main.m; sourceTree = "<group>"; };
|
||||
146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = "<group>"; };
|
||||
1845C223DA364898A8400573 /* FastImage.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = FastImage.xcodeproj; path = "../node_modules/react-native-fast-image/ios/FastImage.xcodeproj"; sourceTree = "<group>"; };
|
||||
1B0746E708284151B8AD1198 /* Ionicons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = file; name = Ionicons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/Ionicons.ttf"; sourceTree = "<group>"; };
|
||||
1D3BB00B9ABF44EA9BD71318 /* libSafariViewManager.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libSafariViewManager.a; sourceTree = "<group>"; };
|
||||
20CE3E407E0D4D9E8C9885F2 /* libRCTVideo.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRCTVideo.a; sourceTree = "<group>"; };
|
||||
22A8B76C8EBA443BB97CE82D /* RNVectorIcons.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNVectorIcons.xcodeproj; path = "../node_modules/react-native-vector-icons/RNVectorIcons.xcodeproj"; sourceTree = "<group>"; };
|
||||
22D3971EAF2E4660B4FAB3DD /* RNI18n.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNI18n.xcodeproj; path = "../node_modules/react-native-i18n/ios/RNI18n.xcodeproj"; sourceTree = "<group>"; };
|
||||
2D02E47B1E0B4A5D006451C7 /* RocketChatRN-tvOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "RocketChatRN-tvOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
2D02E4901E0B4A5D006451C7 /* RocketChatRN-tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "RocketChatRN-tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
2EADB1731B5E47D093292B59 /* MaterialCommunityIcons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = MaterialCommunityIcons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/MaterialCommunityIcons.ttf"; sourceTree = "<group>"; };
|
||||
|
@ -519,6 +545,7 @@
|
|||
7AFB8035205AE63000D004E7 /* RCTToast.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTToast.xcodeproj; path = "../node_modules/@remobile/react-native-toast/ios/RCTToast.xcodeproj"; sourceTree = "<group>"; };
|
||||
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = "<group>"; };
|
||||
8A2DD67ADD954AD9873F45FC /* SimpleLineIcons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = SimpleLineIcons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/SimpleLineIcons.ttf"; sourceTree = "<group>"; };
|
||||
921481B47B50490CA761932E /* libRNI18n.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNI18n.a; sourceTree = "<group>"; };
|
||||
9A1E1766CCB84C91A62BD5A6 /* Foundation.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Foundation.ttf; path = "../node_modules/react-native-vector-icons/Fonts/Foundation.ttf"; sourceTree = "<group>"; };
|
||||
A18EFC3B0CFE40E0918A8F0C /* EvilIcons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = EvilIcons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/EvilIcons.ttf"; sourceTree = "<group>"; };
|
||||
AD0379F2BCE84C968538CDAF /* RCTVideo.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RCTVideo.xcodeproj; path = "../node_modules/react-native-video/ios/RCTVideo.xcodeproj"; sourceTree = "<group>"; };
|
||||
|
@ -528,6 +555,7 @@
|
|||
B8971BAC202A091D0000D245 /* KeyboardTrackingView.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = KeyboardTrackingView.xcodeproj; path = "../node_modules/react-native-keyboard-tracking-view/lib/KeyboardTrackingView.xcodeproj"; sourceTree = "<group>"; };
|
||||
B8C682611FD84CEF003A12C8 /* icomoon.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = icomoon.ttf; path = ../resources/fonts/icomoon.ttf; sourceTree = "<group>"; };
|
||||
BAAE4B947F5D44959F0A9D5A /* libRNZeroconf.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNZeroconf.a; sourceTree = "<group>"; };
|
||||
C01CD6D4653143EEB5100C3A /* libRNI18n-tvOS.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = "libRNI18n-tvOS.a"; sourceTree = "<group>"; };
|
||||
C21010507E5B4B37BA0E4C9D /* RNAudio.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNAudio.xcodeproj; path = "../node_modules/react-native-audio/ios/RNAudio.xcodeproj"; sourceTree = "<group>"; };
|
||||
C23AEF1D9EBE4A38A1A6B97B /* RNSVG.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNSVG.xcodeproj; path = "../node_modules/react-native-svg/ios/RNSVG.xcodeproj"; sourceTree = "<group>"; };
|
||||
DA50CE47374C4C35BE6D9D58 /* libRNSVG.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNSVG.a; sourceTree = "<group>"; };
|
||||
|
@ -535,8 +563,7 @@
|
|||
DF26CC845883492D8AC8869B /* libRealmReact.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRealmReact.a; sourceTree = "<group>"; };
|
||||
E528DE3A405E43B4A37ABA68 /* Zocial.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Zocial.ttf; path = "../node_modules/react-native-vector-icons/Fonts/Zocial.ttf"; sourceTree = "<group>"; };
|
||||
F88C6541BD764BEEABB87272 /* Octicons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Octicons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/Octicons.ttf"; sourceTree = "<group>"; };
|
||||
1845C223DA364898A8400573 /* FastImage.xcodeproj */ = {isa = PBXFileReference; name = "FastImage.xcodeproj"; path = "../node_modules/react-native-fast-image/ios/FastImage.xcodeproj"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = wrapper.pb-project; explicitFileType = undefined; includeInIndex = 0; };
|
||||
FD2E2837F110483CA29EE0D4 /* libFastImage.a */ = {isa = PBXFileReference; name = "libFastImage.a"; path = "libFastImage.a"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; };
|
||||
FD2E2837F110483CA29EE0D4 /* libFastImage.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libFastImage.a; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
|
@ -583,6 +610,7 @@
|
|||
2C800DF680F8451599E80AF1 /* libSafariViewManager.a in Frameworks */,
|
||||
74815BBCB91147C08C8F7B3D /* libRNAudio.a in Frameworks */,
|
||||
BAB7DC22804246F3923A1833 /* libFastImage.a in Frameworks */,
|
||||
F5BF54DC78E1411B8343933B /* libRNI18n.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -598,6 +626,7 @@
|
|||
2D02E4C61E0B4AEC006451C7 /* libRCTSettings-tvOS.a in Frameworks */,
|
||||
2D02E4C71E0B4AEC006451C7 /* libRCTText-tvOS.a in Frameworks */,
|
||||
2D02E4C81E0B4AEC006451C7 /* libRCTWebSocket-tvOS.a in Frameworks */,
|
||||
09CB5909C1E64707832358CE /* libRNI18n-tvOS.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -788,6 +817,23 @@
|
|||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7A770EBC20BECDC7001AD51A /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7A770EC620BECDC7001AD51A /* libRNI18n.a */,
|
||||
7A770EC820BECDC7001AD51A /* libRNI18n-tvOS.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7A770EBE20BECDC7001AD51A /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7A770EC220BECDC7001AD51A /* libFastImage.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7A7F5C831FCC982500024129 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -843,6 +889,7 @@
|
|||
4019A5E1911B4C61944FBCEC /* SafariViewManager.xcodeproj */,
|
||||
C21010507E5B4B37BA0E4C9D /* RNAudio.xcodeproj */,
|
||||
1845C223DA364898A8400573 /* FastImage.xcodeproj */,
|
||||
22D3971EAF2E4660B4FAB3DD /* RNI18n.xcodeproj */,
|
||||
);
|
||||
name = Libraries;
|
||||
sourceTree = "<group>";
|
||||
|
@ -948,6 +995,9 @@
|
|||
B2607FA180F14E6584301101 /* libSplashScreen.a */,
|
||||
1D3BB00B9ABF44EA9BD71318 /* libSafariViewManager.a */,
|
||||
1142E3442BA94B19BCF52814 /* libRNAudio.a */,
|
||||
FD2E2837F110483CA29EE0D4 /* libFastImage.a */,
|
||||
921481B47B50490CA761932E /* libRNI18n.a */,
|
||||
C01CD6D4653143EEB5100C3A /* libRNI18n-tvOS.a */,
|
||||
);
|
||||
name = "Recovered References";
|
||||
sourceTree = "<group>";
|
||||
|
@ -1109,6 +1159,10 @@
|
|||
productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectReferences = (
|
||||
{
|
||||
ProductGroup = 7A770EBE20BECDC7001AD51A /* Products */;
|
||||
ProjectRef = 1845C223DA364898A8400573 /* FastImage.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = B8971BAD202A091D0000D245 /* Products */;
|
||||
ProjectRef = B8971BAC202A091D0000D245 /* KeyboardTrackingView.xcodeproj */;
|
||||
|
@ -1185,6 +1239,10 @@
|
|||
ProductGroup = B8E79A881F3CCC6C005B464F /* Products */;
|
||||
ProjectRef = 4CD38E4891ED4601B7481448 /* RNFetchBlob.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 7A770EBC20BECDC7001AD51A /* Products */;
|
||||
ProjectRef = 22D3971EAF2E4660B4FAB3DD /* RNI18n.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 60B8375C1F3F6F4B00677E56 /* Products */;
|
||||
ProjectRef = 4B38C7E37A8748E0BC665078 /* RNImagePicker.xcodeproj */;
|
||||
|
@ -1463,6 +1521,27 @@
|
|||
remoteRef = 7A430E1D20238C02008F55BC /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
7A770EC220BECDC7001AD51A /* libFastImage.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libFastImage.a;
|
||||
remoteRef = 7A770EC120BECDC7001AD51A /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
7A770EC620BECDC7001AD51A /* libRNI18n.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRNI18n.a;
|
||||
remoteRef = 7A770EC520BECDC7001AD51A /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
7A770EC820BECDC7001AD51A /* libRNI18n-tvOS.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = "libRNI18n-tvOS.a";
|
||||
remoteRef = 7A770EC720BECDC7001AD51A /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
7A7F5C991FCC982500024129 /* libRCTVideo.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
|
@ -1773,6 +1852,7 @@
|
|||
"$(SRCROOT)/../node_modules/react-native-safari-view",
|
||||
"$(SRCROOT)/../node_modules/react-native-audio/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-fast-image/ios/FastImage/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-i18n/ios",
|
||||
);
|
||||
INFOPLIST_FILE = RocketChatRNTests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
|
@ -1787,6 +1867,8 @@
|
|||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
);
|
||||
OTHER_LDFLAGS = (
|
||||
"-ObjC",
|
||||
|
@ -1818,6 +1900,7 @@
|
|||
"$(SRCROOT)/../node_modules/react-native-safari-view",
|
||||
"$(SRCROOT)/../node_modules/react-native-audio/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-fast-image/ios/FastImage/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-i18n/ios",
|
||||
);
|
||||
INFOPLIST_FILE = RocketChatRNTests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
|
@ -1832,6 +1915,8 @@
|
|||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
);
|
||||
OTHER_LDFLAGS = (
|
||||
"-ObjC",
|
||||
|
@ -1873,6 +1958,7 @@
|
|||
"$(SRCROOT)/../node_modules/react-native-audio/ios",
|
||||
"$(SRCROOT)/../../../react-native/React/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-fast-image/ios/FastImage/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-i18n/ios",
|
||||
);
|
||||
INFOPLIST_FILE = RocketChatRN/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
|
@ -1919,6 +2005,7 @@
|
|||
"$(SRCROOT)/../node_modules/react-native-audio/ios",
|
||||
"$(SRCROOT)/../../../react-native/React/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-fast-image/ios/FastImage/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-i18n/ios",
|
||||
);
|
||||
INFOPLIST_FILE = RocketChatRN/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
|
@ -1963,6 +2050,7 @@
|
|||
"$(SRCROOT)/../node_modules/react-native-safari-view",
|
||||
"$(SRCROOT)/../node_modules/react-native-audio/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-fast-image/ios/FastImage/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-i18n/ios",
|
||||
);
|
||||
INFOPLIST_FILE = "RocketChatRN-tvOS/Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
|
@ -1976,6 +2064,8 @@
|
|||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
);
|
||||
OTHER_LDFLAGS = (
|
||||
"-ObjC",
|
||||
|
@ -2017,6 +2107,7 @@
|
|||
"$(SRCROOT)/../node_modules/react-native-safari-view",
|
||||
"$(SRCROOT)/../node_modules/react-native-audio/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-fast-image/ios/FastImage/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-i18n/ios",
|
||||
);
|
||||
INFOPLIST_FILE = "RocketChatRN-tvOS/Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
|
@ -2030,6 +2121,8 @@
|
|||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
);
|
||||
OTHER_LDFLAGS = (
|
||||
"-ObjC",
|
||||
|
@ -2067,6 +2160,8 @@
|
|||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.RocketChatRN-tvOSTests";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
|
@ -2100,6 +2195,8 @@
|
|||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.RocketChatRN-tvOSTests";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
|
|
|
@ -8852,6 +8852,11 @@
|
|||
"resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz",
|
||||
"integrity": "sha1-MRYKNpMK2vH8BMYHT360FGXU7Es="
|
||||
},
|
||||
"i18n-js": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/i18n-js/-/i18n-js-3.0.3.tgz",
|
||||
"integrity": "sha512-u144MQhV/8mz4Y5wP86SQAWMwS8gpe/JavIa9hugSI4WreezGgbhJPdk2Q60KcdIltKLiNefGtHNh1N8SSmQqQ=="
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.19",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
|
||||
|
@ -14806,6 +14811,14 @@
|
|||
"prop-types": "15.6.1"
|
||||
}
|
||||
},
|
||||
"react-native-i18n": {
|
||||
"version": "2.0.12",
|
||||
"resolved": "https://registry.npmjs.org/react-native-i18n/-/react-native-i18n-2.0.12.tgz",
|
||||
"integrity": "sha512-2eTUk7BVZP5knthCmVt6y7rePFwrxXl4ym2I20e91oTYJnKM22sAjQMnLhRCYZWC4ucRBbe2pUp63uxNdTkkQw==",
|
||||
"requires": {
|
||||
"i18n-js": "3.0.3"
|
||||
}
|
||||
},
|
||||
"react-native-image-picker": {
|
||||
"version": "0.26.10",
|
||||
"resolved": "https://registry.npmjs.org/react-native-image-picker/-/react-native-image-picker-0.26.10.tgz",
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
"react-native-fabric": "^0.5.1",
|
||||
"react-native-fast-image": "^4.0.14",
|
||||
"react-native-fetch-blob": "^0.10.8",
|
||||
"react-native-i18n": "^2.0.12",
|
||||
"react-native-image-picker": "^0.26.10",
|
||||
"react-native-keyboard-aware-scroll-view": "^0.5.0",
|
||||
"react-native-keyboard-input": "git+https://github.com/RocketChat/react-native-keyboard-input.git",
|
||||
|
|
Loading…
Reference in New Issue