Attachment types (#118)
* Separate attachment types * Audio attachment file * tmp react-native-video-controls * video working * - Video modal removed * Supported video types check * Audio component * Audio animation * Use a standard ESLint file name * Reusable markdown stateless component * react-native-sound removed * react-native-sound removed from xcode * Url working * Update build.gradle * Other attachments * Fields
This commit is contained in:
parent
e95043bc3f
commit
277adfbb75
|
@ -1,4 +1,4 @@
|
||||||
{
|
module.exports = {
|
||||||
"parser": "babel-eslint",
|
"parser": "babel-eslint",
|
||||||
"extends": "airbnb",
|
"extends": "airbnb",
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
|
@ -120,4 +120,4 @@
|
||||||
"globals": {
|
"globals": {
|
||||||
"__DEV__": true
|
"__DEV__": true
|
||||||
}
|
}
|
||||||
}
|
};
|
|
@ -144,13 +144,14 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
compile project(':react-native-video')
|
||||||
compile project(':react-native-svg')
|
compile project(':react-native-svg')
|
||||||
compile project(':react-native-image-picker')
|
compile project(':react-native-image-picker')
|
||||||
compile project(':react-native-vector-icons')
|
compile project(':react-native-vector-icons')
|
||||||
compile project(':react-native-fetch-blob')
|
compile project(':react-native-fetch-blob')
|
||||||
compile project(':react-native-zeroconf')
|
compile project(':react-native-zeroconf')
|
||||||
compile project(':realm')
|
compile project(':realm')
|
||||||
compile project(':react-native-push-notification')
|
compile project(':react-native-push-notification')
|
||||||
compile fileTree(dir: "libs", include: ["*.jar"])
|
compile fileTree(dir: "libs", include: ["*.jar"])
|
||||||
compile "com.android.support:appcompat-v7:23.0.1"
|
compile "com.android.support:appcompat-v7:23.0.1"
|
||||||
compile "com.facebook.react:react-native:+" // From node_modules
|
compile "com.facebook.react:react-native:+" // From node_modules
|
||||||
|
|
|
@ -14,6 +14,7 @@ import com.facebook.react.ReactPackage;
|
||||||
import com.facebook.react.shell.MainReactPackage;
|
import com.facebook.react.shell.MainReactPackage;
|
||||||
import com.facebook.soloader.SoLoader;
|
import com.facebook.soloader.SoLoader;
|
||||||
import com.dieam.reactnativepushnotification.ReactNativePushNotificationPackage;
|
import com.dieam.reactnativepushnotification.ReactNativePushNotificationPackage;
|
||||||
|
import com.brentvatne.react.ReactVideoPackage;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -35,7 +36,8 @@ public class MainApplication extends Application implements ReactApplication {
|
||||||
new RNFetchBlobPackage(),
|
new RNFetchBlobPackage(),
|
||||||
new ZeroconfReactPackage(),
|
new ZeroconfReactPackage(),
|
||||||
new RealmReactPackage(),
|
new RealmReactPackage(),
|
||||||
new ReactNativePushNotificationPackage()
|
new ReactNativePushNotificationPackage(),
|
||||||
|
new ReactVideoPackage()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
rootProject.name = 'RocketChatRN'
|
rootProject.name = 'RocketChatRN'
|
||||||
|
include ':react-native-video'
|
||||||
|
project(':react-native-video').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-video/android')
|
||||||
include ':react-native-svg'
|
include ':react-native-svg'
|
||||||
project(':react-native-svg').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-svg/android')
|
project(':react-native-svg').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-svg/android')
|
||||||
include ':react-native-image-picker'
|
include ':react-native-image-picker'
|
||||||
|
|
|
@ -76,8 +76,7 @@ export function loginFailure(err) {
|
||||||
export function setToken(user = {}) {
|
export function setToken(user = {}) {
|
||||||
return {
|
return {
|
||||||
type: types.LOGIN.SET_TOKEN,
|
type: types.LOGIN.SET_TOKEN,
|
||||||
token: user.token,
|
...user
|
||||||
user
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,161 @@
|
||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { View, StyleSheet, TouchableOpacity, Text, Easing } from 'react-native';
|
||||||
|
import Video from 'react-native-video';
|
||||||
|
import Icon from 'react-native-vector-icons/MaterialIcons';
|
||||||
|
import Slider from 'react-native-slider';
|
||||||
|
import Markdown from './Markdown';
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
audioContainer: {
|
||||||
|
flex: 1,
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
height: 50,
|
||||||
|
margin: 5,
|
||||||
|
backgroundColor: '#eee',
|
||||||
|
borderRadius: 6
|
||||||
|
},
|
||||||
|
playPauseButton: {
|
||||||
|
width: 50,
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
borderRightColor: '#ccc',
|
||||||
|
borderRightWidth: 1
|
||||||
|
},
|
||||||
|
playPauseIcon: {
|
||||||
|
color: '#ccc',
|
||||||
|
backgroundColor: 'transparent'
|
||||||
|
},
|
||||||
|
progressContainer: {
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: 'center',
|
||||||
|
height: '100%',
|
||||||
|
marginHorizontal: 10
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
color: '#888',
|
||||||
|
fontSize: 10
|
||||||
|
},
|
||||||
|
currentTime: {
|
||||||
|
position: 'absolute',
|
||||||
|
left: 0,
|
||||||
|
bottom: 2
|
||||||
|
},
|
||||||
|
duration: {
|
||||||
|
position: 'absolute',
|
||||||
|
right: 0,
|
||||||
|
bottom: 2
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const formatTime = (t = 0, duration = 0) => {
|
||||||
|
const time = Math.min(
|
||||||
|
Math.max(t, 0),
|
||||||
|
duration
|
||||||
|
);
|
||||||
|
const formattedMinutes = Math.floor(time / 60).toFixed(0).padStart(2, 0);
|
||||||
|
const formattedSeconds = Math.floor(time % 60).toFixed(0).padStart(2, 0);
|
||||||
|
return `${ formattedMinutes }:${ formattedSeconds }`;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default class Audio extends React.PureComponent {
|
||||||
|
static propTypes = {
|
||||||
|
file: PropTypes.object.isRequired,
|
||||||
|
baseUrl: PropTypes.string.isRequired,
|
||||||
|
user: PropTypes.object.isRequired
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.onLoad = this.onLoad.bind(this);
|
||||||
|
this.onProgress = this.onProgress.bind(this);
|
||||||
|
this.onEnd = this.onEnd.bind(this);
|
||||||
|
const { baseUrl, file, user } = props;
|
||||||
|
this.state = {
|
||||||
|
currentTime: 0,
|
||||||
|
duration: 0,
|
||||||
|
paused: true,
|
||||||
|
uri: `${ baseUrl }${ file.audio_url }?rc_uid=${ user.id }&rc_token=${ user.token }`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
onLoad(data) {
|
||||||
|
this.setState({ duration: data.duration });
|
||||||
|
}
|
||||||
|
|
||||||
|
onProgress(data) {
|
||||||
|
if (data.currentTime < this.state.duration) {
|
||||||
|
this.setState({ currentTime: data.currentTime });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onEnd() {
|
||||||
|
this.setState({ paused: true, currentTime: 0 });
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
this.player.seek(0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getCurrentTime() {
|
||||||
|
return formatTime(this.state.currentTime, this.state.duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
getDuration() {
|
||||||
|
return formatTime(this.state.duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
togglePlayPause() {
|
||||||
|
this.setState({ paused: !this.state.paused });
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { uri, paused } = this.state;
|
||||||
|
const { description } = this.props.file;
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<View style={styles.audioContainer}>
|
||||||
|
<Video
|
||||||
|
ref={(ref) => {
|
||||||
|
this.player = ref;
|
||||||
|
}}
|
||||||
|
source={{ uri }}
|
||||||
|
onLoad={this.onLoad}
|
||||||
|
onProgress={this.onProgress}
|
||||||
|
onEnd={this.onEnd}
|
||||||
|
paused={paused}
|
||||||
|
repeat={false}
|
||||||
|
/>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.playPauseButton}
|
||||||
|
onPress={() => this.togglePlayPause()}
|
||||||
|
>
|
||||||
|
{
|
||||||
|
paused ? <Icon name='play-arrow' size={50} style={styles.playPauseIcon} />
|
||||||
|
: <Icon name='pause' size={47} style={styles.playPauseIcon} />
|
||||||
|
}
|
||||||
|
</TouchableOpacity>
|
||||||
|
<View style={styles.progressContainer}>
|
||||||
|
<Text style={[styles.label, styles.currentTime]}>{this.getCurrentTime()}</Text>
|
||||||
|
<Text style={[styles.label, styles.duration]}>{this.getDuration()}</Text>
|
||||||
|
<Slider
|
||||||
|
value={this.state.currentTime}
|
||||||
|
maximumValue={this.state.duration}
|
||||||
|
minimumValue={0}
|
||||||
|
animateTransitions
|
||||||
|
animationConfig={{
|
||||||
|
duration: 250,
|
||||||
|
easing: Easing.linear,
|
||||||
|
delay: 0
|
||||||
|
}}
|
||||||
|
thumbTintColor='#ccc'
|
||||||
|
onValueChange={value => this.setState({ currentTime: value })}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<Markdown msg={description} />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,88 +0,0 @@
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React from 'react';
|
|
||||||
import Meteor from 'react-native-meteor';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { CachedImage } from 'react-native-img-cache';
|
|
||||||
import { Text, TouchableOpacity, View } from 'react-native';
|
|
||||||
import {
|
|
||||||
Card,
|
|
||||||
CardImage,
|
|
||||||
// CardTitle,
|
|
||||||
CardContent
|
|
||||||
// CardAction
|
|
||||||
} from 'react-native-card-view';
|
|
||||||
import RocketChat from '../../lib/rocketchat';
|
|
||||||
|
|
||||||
import PhotoModal from './PhotoModal';
|
|
||||||
|
|
||||||
|
|
||||||
@connect(state => ({
|
|
||||||
base: state.settings.Site_Url,
|
|
||||||
canShowList: state.login.token.length || state.login.user.token
|
|
||||||
}))
|
|
||||||
export default class Cards extends React.PureComponent {
|
|
||||||
static propTypes = {
|
|
||||||
data: PropTypes.object.isRequired,
|
|
||||||
base: PropTypes.string
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
const user = Meteor.user();
|
|
||||||
this.state = {
|
|
||||||
modalVisible: false
|
|
||||||
};
|
|
||||||
RocketChat.getUserToken().then((token) => {
|
|
||||||
this.setState({ img: `${ this.props.base }${ this.props.data.image_url }?rc_uid=${ user._id }&rc_token=${ token }` });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
getDescription() {
|
|
||||||
if (this.props.data.description) {
|
|
||||||
return <Text style={{ alignSelf: 'center', fontWeight: 'bold' }}>{this.props.data.description}</Text>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getImage() {
|
|
||||||
return (
|
|
||||||
<View>
|
|
||||||
<TouchableOpacity onPress={() => this._onPressButton()}>
|
|
||||||
<Card>
|
|
||||||
<CardImage style={{ width: 256, height: 256 }}>
|
|
||||||
<CachedImage
|
|
||||||
style={{ width: 256, height: 256 }}
|
|
||||||
source={{ uri: encodeURI(this.state.img) }}
|
|
||||||
/>
|
|
||||||
</CardImage>
|
|
||||||
<CardContent>
|
|
||||||
<Text style={[{ fontSize: 12, alignSelf: 'center', fontStyle: 'italic' }]}>{this.props.data.title}</Text>
|
|
||||||
{this.getDescription()}
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
</TouchableOpacity>
|
|
||||||
<PhotoModal
|
|
||||||
title={this.props.data.title}
|
|
||||||
image={this.state.img}
|
|
||||||
isVisible={this.state.modalVisible}
|
|
||||||
onClose={() => this.setState({ modalVisible: false })}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
getOther() {
|
|
||||||
return (
|
|
||||||
<Text style={[{ fontSize: 12, alignSelf: 'center', fontStyle: 'italic' }]}>{this.props.data.title}</Text>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
_onPressButton() {
|
|
||||||
this.setState({
|
|
||||||
modalVisible: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return this.state.img ? this.getImage() : this.getOther();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import React from 'react';
|
||||||
|
import { CachedImage } from 'react-native-img-cache';
|
||||||
|
import { Text, TouchableOpacity, View, StyleSheet } from 'react-native';
|
||||||
|
import PhotoModal from './PhotoModal';
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
button: {
|
||||||
|
flex: 1,
|
||||||
|
flexDirection: 'column',
|
||||||
|
height: 320,
|
||||||
|
borderColor: '#ccc',
|
||||||
|
borderWidth: 1,
|
||||||
|
borderRadius: 6
|
||||||
|
},
|
||||||
|
imageContainer: {
|
||||||
|
flex: 1,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center'
|
||||||
|
},
|
||||||
|
image: {
|
||||||
|
width: 256,
|
||||||
|
height: 256,
|
||||||
|
resizeMode: 'cover'
|
||||||
|
},
|
||||||
|
labelContainer: {
|
||||||
|
height: 62,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center'
|
||||||
|
},
|
||||||
|
imageName: {
|
||||||
|
fontSize: 12,
|
||||||
|
alignSelf: 'center',
|
||||||
|
fontStyle: 'italic'
|
||||||
|
},
|
||||||
|
message: {
|
||||||
|
alignSelf: 'center',
|
||||||
|
fontWeight: 'bold'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default class extends React.PureComponent {
|
||||||
|
static propTypes = {
|
||||||
|
file: PropTypes.object.isRequired,
|
||||||
|
baseUrl: PropTypes.string.isRequired,
|
||||||
|
user: PropTypes.object.isRequired
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
const { baseUrl, file, user } = props;
|
||||||
|
this.state = {
|
||||||
|
modalVisible: false,
|
||||||
|
img: `${ baseUrl }${ file.image_url }?rc_uid=${ user.id }&rc_token=${ user.token }`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
getDescription() {
|
||||||
|
if (this.props.file.description) {
|
||||||
|
return <Text style={styles.message}>{this.props.file.description}</Text>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_onPressButton() {
|
||||||
|
this.setState({
|
||||||
|
modalVisible: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={() => this._onPressButton()}
|
||||||
|
style={styles.button}
|
||||||
|
>
|
||||||
|
<View style={styles.imageContainer}>
|
||||||
|
<CachedImage
|
||||||
|
style={styles.image}
|
||||||
|
source={{ uri: encodeURI(this.state.img) }}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<View style={styles.labelContainer}>
|
||||||
|
<Text style={styles.imageName}>{this.props.file.title}</Text>
|
||||||
|
{this.getDescription()}
|
||||||
|
</View>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<PhotoModal
|
||||||
|
title={this.props.file.title}
|
||||||
|
image={this.state.img}
|
||||||
|
isVisible={this.state.modalVisible}
|
||||||
|
onClose={() => this.setState({ modalVisible: false })}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import EasyMarkdown from 'react-native-easy-markdown'; // eslint-disable-line
|
||||||
|
import { emojify } from 'react-emojione';
|
||||||
|
|
||||||
|
const Markdown = ({ msg }) => {
|
||||||
|
if (!msg) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
msg = emojify(msg, { output: 'unicode' });
|
||||||
|
return <EasyMarkdown>{msg}</EasyMarkdown>;
|
||||||
|
};
|
||||||
|
|
||||||
|
Markdown.propTypes = {
|
||||||
|
msg: PropTypes.string.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Markdown;
|
|
@ -0,0 +1,20 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { View, StyleSheet } from 'react-native';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
quoteSign: {
|
||||||
|
borderWidth: 2,
|
||||||
|
borderRadius: 4,
|
||||||
|
height: '100%',
|
||||||
|
marginRight: 5
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const QuoteMark = ({ color }) => <View style={[styles.quoteSign, { borderColor: color || '#a0a0a0' }]} />;
|
||||||
|
|
||||||
|
QuoteMark.propTypes = {
|
||||||
|
color: PropTypes.string
|
||||||
|
};
|
||||||
|
|
||||||
|
export default QuoteMark;
|
|
@ -0,0 +1,134 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { View, Text, TouchableOpacity, StyleSheet, Linking } from 'react-native';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import moment from 'moment';
|
||||||
|
|
||||||
|
import Markdown from './Markdown';
|
||||||
|
import QuoteMark from './QuoteMark';
|
||||||
|
import Avatar from '../Avatar';
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
button: {
|
||||||
|
flex: 1,
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
marginTop: 2,
|
||||||
|
alignSelf: 'flex-end'
|
||||||
|
},
|
||||||
|
quoteSign: {
|
||||||
|
borderWidth: 2,
|
||||||
|
borderRadius: 4,
|
||||||
|
borderColor: '#a0a0a0',
|
||||||
|
height: '100%',
|
||||||
|
marginRight: 5
|
||||||
|
},
|
||||||
|
attachmentContainer: {
|
||||||
|
flex: 1,
|
||||||
|
flexDirection: 'column'
|
||||||
|
},
|
||||||
|
authorContainer: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center'
|
||||||
|
},
|
||||||
|
time: {
|
||||||
|
fontSize: 10,
|
||||||
|
fontWeight: 'normal',
|
||||||
|
color: '#888',
|
||||||
|
marginLeft: 5
|
||||||
|
},
|
||||||
|
fieldsContainer: {
|
||||||
|
flex: 1,
|
||||||
|
flexWrap: 'wrap',
|
||||||
|
flexDirection: 'row'
|
||||||
|
},
|
||||||
|
fieldContainer: {
|
||||||
|
flexDirection: 'column',
|
||||||
|
padding: 10
|
||||||
|
},
|
||||||
|
fieldTitle: {
|
||||||
|
fontWeight: 'bold'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const onPress = (attachment) => {
|
||||||
|
const url = attachment.title_link || attachment.author_link;
|
||||||
|
if (!url) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Linking.openURL(attachment.title_link || attachment.author_link);
|
||||||
|
};
|
||||||
|
const Reply = ({ attachment, timeFormat }) => {
|
||||||
|
if (!attachment) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const renderAvatar = () => {
|
||||||
|
if (!attachment.author_icon && !attachment.author_name) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Avatar
|
||||||
|
style={{ marginLeft: 5 }}
|
||||||
|
text={attachment.author_name}
|
||||||
|
size={16}
|
||||||
|
avatar={attachment.author_icon}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderAuthor = () => (
|
||||||
|
attachment.author_name ? <Text style={{ fontWeight: 'bold' }}>{attachment.author_name}</Text> : null
|
||||||
|
);
|
||||||
|
|
||||||
|
const renderTime = () => {
|
||||||
|
const time = attachment.ts ? moment(attachment.ts).format(timeFormat) : null;
|
||||||
|
return time ? <Text style={styles.time}>{ time }</Text> : null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderText = () => (
|
||||||
|
attachment.text ? <Markdown msg={attachment.text} /> : null
|
||||||
|
);
|
||||||
|
|
||||||
|
const renderFields = () => {
|
||||||
|
if (!attachment.fields) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.fieldsContainer}>
|
||||||
|
{attachment.fields.map(field => (
|
||||||
|
<View key={field.title} style={[styles.fieldContainer, { width: field.short ? '50%' : '100%' }]}>
|
||||||
|
<Text style={styles.fieldTitle}>{field.title}</Text>
|
||||||
|
<Text>{field.value}</Text>
|
||||||
|
</View>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={() => onPress(attachment)}
|
||||||
|
style={styles.button}
|
||||||
|
>
|
||||||
|
<QuoteMark color={attachment.color} />
|
||||||
|
<View style={styles.attachmentContainer}>
|
||||||
|
<View style={styles.authorContainer}>
|
||||||
|
<Text>
|
||||||
|
{renderAvatar()} {renderAuthor()} {renderTime()}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
{renderText()}
|
||||||
|
{renderFields()}
|
||||||
|
{attachment.attachments.map(attach => <Reply key={attach.text} attachment={attach} timeFormat={timeFormat} />)}
|
||||||
|
</View>
|
||||||
|
</TouchableOpacity>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
Reply.propTypes = {
|
||||||
|
attachment: PropTypes.object.isRequired,
|
||||||
|
timeFormat: PropTypes.string.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Reply;
|
|
@ -0,0 +1,70 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { View, Text, TouchableOpacity, Linking, StyleSheet, Image } from 'react-native';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
import QuoteMark from './QuoteMark';
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
button: {
|
||||||
|
flex: 1,
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
marginVertical: 2
|
||||||
|
},
|
||||||
|
quoteSign: {
|
||||||
|
borderWidth: 2,
|
||||||
|
borderRadius: 4,
|
||||||
|
borderColor: '#a0a0a0',
|
||||||
|
height: '100%',
|
||||||
|
marginRight: 5
|
||||||
|
},
|
||||||
|
image: {
|
||||||
|
height: 80,
|
||||||
|
width: 80,
|
||||||
|
resizeMode: 'cover',
|
||||||
|
borderRadius: 6
|
||||||
|
},
|
||||||
|
textContainer: {
|
||||||
|
flex: 1,
|
||||||
|
height: '100%',
|
||||||
|
flexDirection: 'column',
|
||||||
|
padding: 4,
|
||||||
|
justifyContent: 'flex-start',
|
||||||
|
alignItems: 'flex-start'
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontWeight: 'bold',
|
||||||
|
fontSize: 12
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
fontSize: 12
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const onPress = (url) => {
|
||||||
|
Linking.openURL(url);
|
||||||
|
};
|
||||||
|
const Url = ({ url }) => {
|
||||||
|
if (!url) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<TouchableOpacity onPress={() => onPress(url.url)} style={styles.button}>
|
||||||
|
<QuoteMark />
|
||||||
|
<Image
|
||||||
|
style={styles.image}
|
||||||
|
source={{ uri: encodeURI(url.image) }}
|
||||||
|
/>
|
||||||
|
<View style={styles.textContainer}>
|
||||||
|
<Text style={styles.title}>{url.title}</Text>
|
||||||
|
<Text style={styles.description} numberOfLines={1}>{url.description}</Text>
|
||||||
|
</View>
|
||||||
|
</TouchableOpacity>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
Url.propTypes = {
|
||||||
|
url: PropTypes.object.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Url;
|
|
@ -0,0 +1,88 @@
|
||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { View, StyleSheet, TouchableOpacity, Image, Linking, Platform } from 'react-native';
|
||||||
|
import Modal from 'react-native-modal';
|
||||||
|
import VideoPlayer from 'react-native-video-controls';
|
||||||
|
import Markdown from './Markdown';
|
||||||
|
|
||||||
|
const SUPPORTED_TYPES = ['video/quicktime', 'video/mp4', ...(Platform.OS === 'ios' ? [] : ['video/webm', 'video/3gp', 'video/mkv'])];
|
||||||
|
const isTypeSupported = type => SUPPORTED_TYPES.indexOf(type) !== -1;
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
height: 100,
|
||||||
|
margin: 5
|
||||||
|
},
|
||||||
|
modal: {
|
||||||
|
margin: 0,
|
||||||
|
backgroundColor: '#000'
|
||||||
|
},
|
||||||
|
image: {
|
||||||
|
flex: 1,
|
||||||
|
width: null,
|
||||||
|
height: null,
|
||||||
|
resizeMode: 'contain'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default class Video extends React.PureComponent {
|
||||||
|
static propTypes = {
|
||||||
|
file: PropTypes.object.isRequired,
|
||||||
|
baseUrl: PropTypes.string.isRequired,
|
||||||
|
user: PropTypes.object.isRequired
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
const { baseUrl, file, user } = props;
|
||||||
|
this.state = {
|
||||||
|
isVisible: false,
|
||||||
|
uri: `${ baseUrl }${ file.video_url }?rc_uid=${ user.id }&rc_token=${ user.token }`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
toggleModal() {
|
||||||
|
this.setState({
|
||||||
|
isVisible: !this.state.isVisible
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
open() {
|
||||||
|
if (isTypeSupported(this.props.file.video_type)) {
|
||||||
|
return this.toggleModal();
|
||||||
|
}
|
||||||
|
Linking.openURL(this.state.uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { isVisible, uri } = this.state;
|
||||||
|
const { description } = this.props.file;
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.container}
|
||||||
|
onPress={() => this.open()}
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
source={require('../../images/logo.png')}
|
||||||
|
style={styles.image}
|
||||||
|
/>
|
||||||
|
<Markdown msg={description} />
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Modal
|
||||||
|
isVisible={isVisible}
|
||||||
|
style={styles.modal}
|
||||||
|
supportedOrientations={['portrait', 'landscape']}
|
||||||
|
>
|
||||||
|
<VideoPlayer
|
||||||
|
source={{ uri }}
|
||||||
|
onBack={() => this.toggleModal()}
|
||||||
|
disableVolume
|
||||||
|
/>
|
||||||
|
</Modal>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,14 +1,17 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { View, StyleSheet, TouchableOpacity, Text } from 'react-native';
|
import { View, StyleSheet, TouchableOpacity, Text } from 'react-native';
|
||||||
import { emojify } from 'react-emojione';
|
|
||||||
import Markdown from 'react-native-easy-markdown'; // eslint-disable-line
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { actionsShow } from '../../actions/messages';
|
import { actionsShow } from '../../actions/messages';
|
||||||
import Card from './Card';
|
import Image from './Image';
|
||||||
import User from './User';
|
import User from './User';
|
||||||
import Avatar from '../Avatar';
|
import Avatar from '../Avatar';
|
||||||
|
import Audio from './Audio';
|
||||||
|
import Video from './Video';
|
||||||
|
import Markdown from './Markdown';
|
||||||
|
import Url from './Url';
|
||||||
|
import Reply from './Reply';
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
content: {
|
content: {
|
||||||
|
@ -43,6 +46,7 @@ export default class Message extends React.Component {
|
||||||
baseUrl: PropTypes.string.isRequired,
|
baseUrl: PropTypes.string.isRequired,
|
||||||
Message_TimeFormat: PropTypes.string.isRequired,
|
Message_TimeFormat: PropTypes.string.isRequired,
|
||||||
message: PropTypes.object.isRequired,
|
message: PropTypes.object.isRequired,
|
||||||
|
user: PropTypes.object.isRequired,
|
||||||
editing: PropTypes.bool,
|
editing: PropTypes.bool,
|
||||||
actionsShow: PropTypes.func
|
actionsShow: PropTypes.func
|
||||||
}
|
}
|
||||||
|
@ -53,28 +57,48 @@ export default class Message extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
isDeleted() {
|
isDeleted() {
|
||||||
return !this.props.item.msg;
|
return this.props.item.t === 'rm';
|
||||||
|
}
|
||||||
|
|
||||||
|
isPinned() {
|
||||||
|
return this.props.item.t === 'message_pinned';
|
||||||
}
|
}
|
||||||
|
|
||||||
attachments() {
|
attachments() {
|
||||||
return this.props.item.attachments.length ? (
|
if (this.props.item.attachments.length === 0) {
|
||||||
<Card
|
return null;
|
||||||
data={this.props.item.attachments[0]}
|
}
|
||||||
/>
|
|
||||||
) : null;
|
const file = this.props.item.attachments[0];
|
||||||
|
const { baseUrl, user } = this.props;
|
||||||
|
if (file.image_type) {
|
||||||
|
return <Image file={file} baseUrl={baseUrl} user={user} />;
|
||||||
|
} else if (file.audio_type) {
|
||||||
|
return <Audio file={file} baseUrl={baseUrl} user={user} />;
|
||||||
|
} else if (file.video_type) {
|
||||||
|
return <Video file={file} baseUrl={baseUrl} user={user} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <Reply attachment={file} timeFormat={this.props.Message_TimeFormat} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderMessageContent() {
|
renderMessageContent() {
|
||||||
if (this.isDeleted()) {
|
if (this.isDeleted()) {
|
||||||
return <Text style={styles.textInfo}>Message removed</Text>;
|
return <Text style={styles.textInfo}>Message removed</Text>;
|
||||||
|
} else if (this.isPinned()) {
|
||||||
|
return <Text style={styles.textInfo}>Message pinned</Text>;
|
||||||
|
}
|
||||||
|
return <Markdown msg={this.props.item.msg} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderUrl() {
|
||||||
|
if (this.props.item.urls.length === 0) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const msg = emojify(this.props.item.msg, { output: 'unicode' });
|
return this.props.item.urls.map(url => (
|
||||||
return (
|
<Url url={url} key={url._id} />
|
||||||
<Markdown>
|
));
|
||||||
{msg}
|
|
||||||
</Markdown>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -110,8 +134,9 @@ export default class Message extends React.Component {
|
||||||
Message_TimeFormat={this.props.Message_TimeFormat}
|
Message_TimeFormat={this.props.Message_TimeFormat}
|
||||||
baseUrl={this.props.baseUrl}
|
baseUrl={this.props.baseUrl}
|
||||||
/>
|
/>
|
||||||
|
{this.renderMessageContent()}
|
||||||
{this.attachments()}
|
{this.attachments()}
|
||||||
{this.renderMessageContent(item)}
|
{this.renderUrl()}
|
||||||
</View>
|
</View>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
);
|
);
|
||||||
|
|
|
@ -95,24 +95,55 @@ const usersSchema = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const attachmentFields = {
|
||||||
|
name: 'attachmentFields',
|
||||||
|
properties: {
|
||||||
|
title: { type: 'string', optional: true },
|
||||||
|
value: { type: 'string', optional: true },
|
||||||
|
short: { type: 'bool', optional: true }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const attachment = {
|
const attachment = {
|
||||||
name: 'attachment',
|
name: 'attachment',
|
||||||
properties: {
|
properties: {
|
||||||
description: { type: 'string', optional: true },
|
description: { type: 'string', optional: true },
|
||||||
|
|
||||||
image_size: { type: 'int', optional: true },
|
image_size: { type: 'int', optional: true },
|
||||||
|
|
||||||
image_type: { type: 'string', optional: true },
|
image_type: { type: 'string', optional: true },
|
||||||
|
|
||||||
image_url: { type: 'string', optional: true },
|
image_url: { type: 'string', optional: true },
|
||||||
|
audio_size: { type: 'int', optional: true },
|
||||||
|
audio_type: { type: 'string', optional: true },
|
||||||
|
audio_url: { type: 'string', optional: true },
|
||||||
|
video_size: { type: 'int', optional: true },
|
||||||
|
video_type: { type: 'string', optional: true },
|
||||||
|
video_url: { type: 'string', optional: true },
|
||||||
title: { type: 'string', optional: true },
|
title: { type: 'string', optional: true },
|
||||||
|
|
||||||
title_link: { type: 'string', optional: true },
|
title_link: { type: 'string', optional: true },
|
||||||
title_link_download: { type: 'bool', optional: true },
|
title_link_download: { type: 'bool', optional: true },
|
||||||
type: { type: 'string', optional: true }
|
type: { type: 'string', optional: true },
|
||||||
|
author_icon: { type: 'string', optional: true },
|
||||||
|
author_name: { type: 'string', optional: true },
|
||||||
|
author_link: { type: 'string', optional: true },
|
||||||
|
text: { type: 'string', optional: true },
|
||||||
|
color: { type: 'string', optional: true },
|
||||||
|
ts: { type: 'date', optional: true },
|
||||||
|
attachments: { type: 'list', objectType: 'attachment' },
|
||||||
|
fields: { type: 'list', objectType: 'attachmentFields' }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const url = {
|
||||||
|
name: 'url',
|
||||||
|
properties: {
|
||||||
|
_id: 'int',
|
||||||
|
url: { type: 'string', optional: true },
|
||||||
|
title: { type: 'string', optional: true },
|
||||||
|
description: { type: 'string', optional: true },
|
||||||
|
image: { type: 'string', optional: true }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
const messagesEditedBySchema = {
|
const messagesEditedBySchema = {
|
||||||
name: 'messagesEditedBy',
|
name: 'messagesEditedBy',
|
||||||
properties: {
|
properties: {
|
||||||
|
@ -128,6 +159,7 @@ const messagesSchema = {
|
||||||
_id: 'string',
|
_id: 'string',
|
||||||
_server: 'servers',
|
_server: 'servers',
|
||||||
msg: { type: 'string', optional: true },
|
msg: { type: 'string', optional: true },
|
||||||
|
t: { type: 'string', optional: true },
|
||||||
rid: 'string',
|
rid: 'string',
|
||||||
ts: 'date',
|
ts: 'date',
|
||||||
u: 'users',
|
u: 'users',
|
||||||
|
@ -138,6 +170,7 @@ const messagesSchema = {
|
||||||
groupable: { type: 'bool', optional: true },
|
groupable: { type: 'bool', optional: true },
|
||||||
avatar: { type: 'string', optional: true },
|
avatar: { type: 'string', optional: true },
|
||||||
attachments: { type: 'list', objectType: 'attachment' },
|
attachments: { type: 'list', objectType: 'attachment' },
|
||||||
|
urls: { type: 'list', objectType: 'url' },
|
||||||
_updatedAt: { type: 'date', optional: true },
|
_updatedAt: { type: 'date', optional: true },
|
||||||
temp: { type: 'bool', optional: true },
|
temp: { type: 'bool', optional: true },
|
||||||
pinned: { type: 'bool', optional: true },
|
pinned: { type: 'bool', optional: true },
|
||||||
|
@ -158,9 +191,11 @@ const realm = new Realm({
|
||||||
usersSchema,
|
usersSchema,
|
||||||
roomsSchema,
|
roomsSchema,
|
||||||
attachment,
|
attachment,
|
||||||
|
attachmentFields,
|
||||||
messagesEditedBySchema,
|
messagesEditedBySchema,
|
||||||
permissionsSchema,
|
permissionsSchema,
|
||||||
permissionsRolesSchema
|
permissionsRolesSchema,
|
||||||
|
url
|
||||||
],
|
],
|
||||||
deleteRealmIfMigrationNeeded: true
|
deleteRealmIfMigrationNeeded: true
|
||||||
});
|
});
|
||||||
|
|
|
@ -63,14 +63,9 @@ const RocketChat = {
|
||||||
|
|
||||||
Meteor.ddp.on('connected', async() => {
|
Meteor.ddp.on('connected', async() => {
|
||||||
Meteor.ddp.on('changed', (ddpMessage) => {
|
Meteor.ddp.on('changed', (ddpMessage) => {
|
||||||
const server = { id: reduxStore.getState().server.server };
|
|
||||||
if (ddpMessage.collection === 'stream-room-messages') {
|
if (ddpMessage.collection === 'stream-room-messages') {
|
||||||
return realm.write(() => {
|
return realm.write(() => {
|
||||||
const message = ddpMessage.fields.args[0];
|
const message = this._buildMessage(ddpMessage.fields.args[0]);
|
||||||
message.temp = false;
|
|
||||||
message._server = server;
|
|
||||||
message.attachments = message.attachments || [];
|
|
||||||
message.starred = message.starred && message.starred.length > 0;
|
|
||||||
realm.create('messages', message, true);
|
realm.create('messages', message, true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -246,6 +241,35 @@ const RocketChat = {
|
||||||
return call('raix:push-setuser', pushId);
|
return call('raix:push-setuser', pushId);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_parseUrls(urls) {
|
||||||
|
return urls.filter(url => url.meta && !url.ignoreParse).map((url, index) => {
|
||||||
|
const tmp = {};
|
||||||
|
const { meta } = url;
|
||||||
|
tmp._id = index;
|
||||||
|
tmp.title = meta.ogTitle || meta.twitterTitle || meta.title || meta.pageTitle || meta.oembedTitle;
|
||||||
|
tmp.description = meta.ogDescription || meta.twitterDescription || meta.description || meta.oembedAuthorName;
|
||||||
|
let decodedOgImage;
|
||||||
|
if (meta.ogImage) {
|
||||||
|
decodedOgImage = meta.ogImage.replace(/&/g, '&');
|
||||||
|
}
|
||||||
|
tmp.image = decodedOgImage || meta.twitterImage || meta.oembedThumbnailUrl;
|
||||||
|
tmp.url = url.url;
|
||||||
|
return tmp;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
_buildMessage(message) {
|
||||||
|
const { server } = reduxStore.getState().server;
|
||||||
|
message.temp = false;
|
||||||
|
message._server = { id: server };
|
||||||
|
message.attachments = message.attachments || [];
|
||||||
|
if (message.urls) {
|
||||||
|
message.urls = RocketChat._parseUrls(message.urls);
|
||||||
|
}
|
||||||
|
// loadHistory returns message.starred as object
|
||||||
|
// stream-room-messages returns message.starred as an array
|
||||||
|
message.starred = message.starred && (Array.isArray(message.starred) ? message.starred.length > 0 : !!message.starred);
|
||||||
|
return message;
|
||||||
|
},
|
||||||
loadMessagesForRoom(rid, end, cb) {
|
loadMessagesForRoom(rid, end, cb) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
Meteor.call('loadHistory', rid, end, 20, (err, data) => {
|
Meteor.call('loadHistory', rid, end, 20, (err, data) => {
|
||||||
|
@ -256,13 +280,9 @@ const RocketChat = {
|
||||||
return reject(err);
|
return reject(err);
|
||||||
}
|
}
|
||||||
if (data && data.messages.length) {
|
if (data && data.messages.length) {
|
||||||
|
const messages = data.messages.map(message => this._buildMessage(message));
|
||||||
realm.write(() => {
|
realm.write(() => {
|
||||||
data.messages.forEach((message) => {
|
messages.forEach((message) => {
|
||||||
message.temp = false;
|
|
||||||
message._server = { id: reduxStore.getState().server.server };
|
|
||||||
message.attachments = message.attachments || [];
|
|
||||||
// write('messages', message);
|
|
||||||
message.starred = !!message.starred;
|
|
||||||
realm.create('messages', message, true);
|
realm.create('messages', message, true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -55,7 +55,8 @@ const typing = () => <Typing />;
|
||||||
server: state.server.server,
|
server: state.server.server,
|
||||||
Site_Url: state.settings.Site_Url,
|
Site_Url: state.settings.Site_Url,
|
||||||
Message_TimeFormat: state.settings.Message_TimeFormat,
|
Message_TimeFormat: state.settings.Message_TimeFormat,
|
||||||
loading: state.messages.isFetching
|
loading: state.messages.isFetching,
|
||||||
|
user: state.login.user
|
||||||
}),
|
}),
|
||||||
dispatch => ({
|
dispatch => ({
|
||||||
actions: bindActionCreators(actions, dispatch),
|
actions: bindActionCreators(actions, dispatch),
|
||||||
|
@ -67,6 +68,7 @@ export default class RoomView extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
navigation: PropTypes.object.isRequired,
|
navigation: PropTypes.object.isRequired,
|
||||||
openRoom: PropTypes.func.isRequired,
|
openRoom: PropTypes.func.isRequired,
|
||||||
|
user: PropTypes.object.isRequired,
|
||||||
editCancel: PropTypes.func,
|
editCancel: PropTypes.func,
|
||||||
rid: PropTypes.string,
|
rid: PropTypes.string,
|
||||||
server: PropTypes.string,
|
server: PropTypes.string,
|
||||||
|
@ -163,6 +165,7 @@ export default class RoomView extends React.Component {
|
||||||
item={item}
|
item={item}
|
||||||
baseUrl={this.props.Site_Url}
|
baseUrl={this.props.Site_Url}
|
||||||
Message_TimeFormat={this.props.Message_TimeFormat}
|
Message_TimeFormat={this.props.Message_TimeFormat}
|
||||||
|
user={this.props.user}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
77C35F50C01C43668188886C /* libRNVectorIcons.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A0EEFAF8AB14F5B9E796CDD /* libRNVectorIcons.a */; };
|
77C35F50C01C43668188886C /* libRNVectorIcons.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A0EEFAF8AB14F5B9E796CDD /* libRNVectorIcons.a */; };
|
||||||
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
|
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
|
||||||
8A159EDB97C44E52AF62D69C /* libRNSVG.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DA50CE47374C4C35BE6D9D58 /* libRNSVG.a */; };
|
8A159EDB97C44E52AF62D69C /* libRNSVG.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DA50CE47374C4C35BE6D9D58 /* libRNSVG.a */; };
|
||||||
|
8ECBD927DDAC4987B98E102E /* libRCTVideo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 20CE3E407E0D4D9E8C9885F2 /* libRCTVideo.a */; };
|
||||||
AE5D35882AE04CC29630FB3D /* Entypo.ttf in Resources */ = {isa = PBXBuildFile; fileRef = DC6EE17B5550465E98C70FF0 /* Entypo.ttf */; };
|
AE5D35882AE04CC29630FB3D /* Entypo.ttf in Resources */ = {isa = PBXBuildFile; fileRef = DC6EE17B5550465E98C70FF0 /* Entypo.ttf */; };
|
||||||
B88F586F1FBF57F600B352B8 /* libRCTPushNotification.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B88F58461FBF55E200B352B8 /* libRCTPushNotification.a */; };
|
B88F586F1FBF57F600B352B8 /* libRCTPushNotification.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B88F58461FBF55E200B352B8 /* libRCTPushNotification.a */; };
|
||||||
B8E79AF41F3CD167005B464F /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB61A68108700A75B9A /* Info.plist */; };
|
B8E79AF41F3CD167005B464F /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB61A68108700A75B9A /* Info.plist */; };
|
||||||
|
@ -290,6 +291,20 @@
|
||||||
remoteGlobalIDString = 134814201AA4EA6300B7C361;
|
remoteGlobalIDString = 134814201AA4EA6300B7C361;
|
||||||
remoteInfo = RCTLinking;
|
remoteInfo = RCTLinking;
|
||||||
};
|
};
|
||||||
|
7A7F5C981FCC982500024129 /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = AD0379F2BCE84C968538CDAF /* RCTVideo.xcodeproj */;
|
||||||
|
proxyType = 2;
|
||||||
|
remoteGlobalIDString = 134814201AA4EA6300B7C361;
|
||||||
|
remoteInfo = RCTVideo;
|
||||||
|
};
|
||||||
|
7A7F5C9A1FCC982500024129 /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = AD0379F2BCE84C968538CDAF /* RCTVideo.xcodeproj */;
|
||||||
|
proxyType = 2;
|
||||||
|
remoteGlobalIDString = 641E28441F0EEC8500443AF6;
|
||||||
|
remoteInfo = "RCTVideo-tvOS";
|
||||||
|
};
|
||||||
832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */ = {
|
832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */ = {
|
||||||
isa = PBXContainerItemProxy;
|
isa = PBXContainerItemProxy;
|
||||||
containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;
|
containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;
|
||||||
|
@ -391,6 +406,7 @@
|
||||||
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = RocketChatRN/main.m; 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>"; };
|
146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = "<group>"; };
|
||||||
1B0746E708284151B8AD1198 /* Ionicons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Ionicons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/Ionicons.ttf"; sourceTree = "<group>"; };
|
1B0746E708284151B8AD1198 /* Ionicons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Ionicons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/Ionicons.ttf"; 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>"; };
|
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>"; };
|
||||||
2D02E47B1E0B4A5D006451C7 /* RocketChatRN-tvOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "RocketChatRN-tvOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
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; };
|
2D02E4901E0B4A5D006451C7 /* RocketChatRN-tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "RocketChatRN-tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
@ -411,6 +427,7 @@
|
||||||
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>"; };
|
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>"; };
|
||||||
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>"; };
|
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>"; };
|
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>"; };
|
||||||
B37C79D9BD0742CE936B6982 /* libc++.tbd */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; };
|
B37C79D9BD0742CE936B6982 /* libc++.tbd */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; };
|
||||||
B88F58361FBF55E200B352B8 /* RCTPushNotification.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTPushNotification.xcodeproj; path = "../node_modules/react-native/Libraries/PushNotificationIOS/RCTPushNotification.xcodeproj"; sourceTree = "<group>"; };
|
B88F58361FBF55E200B352B8 /* RCTPushNotification.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTPushNotification.xcodeproj; path = "../node_modules/react-native/Libraries/PushNotificationIOS/RCTPushNotification.xcodeproj"; sourceTree = "<group>"; };
|
||||||
BAAE4B947F5D44959F0A9D5A /* libRNZeroconf.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNZeroconf.a; sourceTree = "<group>"; };
|
BAAE4B947F5D44959F0A9D5A /* libRNZeroconf.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNZeroconf.a; sourceTree = "<group>"; };
|
||||||
|
@ -455,6 +472,7 @@
|
||||||
77C35F50C01C43668188886C /* libRNVectorIcons.a in Frameworks */,
|
77C35F50C01C43668188886C /* libRNVectorIcons.a in Frameworks */,
|
||||||
8A159EDB97C44E52AF62D69C /* libRNSVG.a in Frameworks */,
|
8A159EDB97C44E52AF62D69C /* libRNSVG.a in Frameworks */,
|
||||||
C758F0BD5C3244E2BA073E61 /* libRNImagePicker.a in Frameworks */,
|
C758F0BD5C3244E2BA073E61 /* libRNImagePicker.a in Frameworks */,
|
||||||
|
8ECBD927DDAC4987B98E102E /* libRCTVideo.a in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
@ -640,6 +658,15 @@
|
||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
7A7F5C831FCC982500024129 /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
7A7F5C991FCC982500024129 /* libRCTVideo.a */,
|
||||||
|
7A7F5C9B1FCC982500024129 /* libRCTVideo.a */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
832341AE1AAA6A7D00B99B32 /* Libraries */ = {
|
832341AE1AAA6A7D00B99B32 /* Libraries */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -661,6 +688,7 @@
|
||||||
22A8B76C8EBA443BB97CE82D /* RNVectorIcons.xcodeproj */,
|
22A8B76C8EBA443BB97CE82D /* RNVectorIcons.xcodeproj */,
|
||||||
C23AEF1D9EBE4A38A1A6B97B /* RNSVG.xcodeproj */,
|
C23AEF1D9EBE4A38A1A6B97B /* RNSVG.xcodeproj */,
|
||||||
4B38C7E37A8748E0BC665078 /* RNImagePicker.xcodeproj */,
|
4B38C7E37A8748E0BC665078 /* RNImagePicker.xcodeproj */,
|
||||||
|
AD0379F2BCE84C968538CDAF /* RCTVideo.xcodeproj */,
|
||||||
);
|
);
|
||||||
name = Libraries;
|
name = Libraries;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -735,6 +763,7 @@
|
||||||
5A0EEFAF8AB14F5B9E796CDD /* libRNVectorIcons.a */,
|
5A0EEFAF8AB14F5B9E796CDD /* libRNVectorIcons.a */,
|
||||||
DA50CE47374C4C35BE6D9D58 /* libRNSVG.a */,
|
DA50CE47374C4C35BE6D9D58 /* libRNSVG.a */,
|
||||||
3B696712EE2345A59F007A88 /* libRNImagePicker.a */,
|
3B696712EE2345A59F007A88 /* libRNImagePicker.a */,
|
||||||
|
20CE3E407E0D4D9E8C9885F2 /* libRCTVideo.a */,
|
||||||
);
|
);
|
||||||
name = "Recovered References";
|
name = "Recovered References";
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -936,6 +965,10 @@
|
||||||
ProductGroup = 00C302E01ABCB9EE00DB3ED1 /* Products */;
|
ProductGroup = 00C302E01ABCB9EE00DB3ED1 /* Products */;
|
||||||
ProjectRef = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */;
|
ProjectRef = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */;
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
ProductGroup = 7A7F5C831FCC982500024129 /* Products */;
|
||||||
|
ProjectRef = AD0379F2BCE84C968538CDAF /* RCTVideo.xcodeproj */;
|
||||||
|
},
|
||||||
{
|
{
|
||||||
ProductGroup = 139FDEE71B06529A00C62182 /* Products */;
|
ProductGroup = 139FDEE71B06529A00C62182 /* Products */;
|
||||||
ProjectRef = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;
|
ProjectRef = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;
|
||||||
|
@ -1197,6 +1230,20 @@
|
||||||
remoteRef = 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */;
|
remoteRef = 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */;
|
||||||
sourceTree = BUILT_PRODUCTS_DIR;
|
sourceTree = BUILT_PRODUCTS_DIR;
|
||||||
};
|
};
|
||||||
|
7A7F5C991FCC982500024129 /* libRCTVideo.a */ = {
|
||||||
|
isa = PBXReferenceProxy;
|
||||||
|
fileType = archive.ar;
|
||||||
|
path = libRCTVideo.a;
|
||||||
|
remoteRef = 7A7F5C981FCC982500024129 /* PBXContainerItemProxy */;
|
||||||
|
sourceTree = BUILT_PRODUCTS_DIR;
|
||||||
|
};
|
||||||
|
7A7F5C9B1FCC982500024129 /* libRCTVideo.a */ = {
|
||||||
|
isa = PBXReferenceProxy;
|
||||||
|
fileType = archive.ar;
|
||||||
|
path = libRCTVideo.a;
|
||||||
|
remoteRef = 7A7F5C9A1FCC982500024129 /* PBXContainerItemProxy */;
|
||||||
|
sourceTree = BUILT_PRODUCTS_DIR;
|
||||||
|
};
|
||||||
832341B51AAA6A8300B99B32 /* libRCTText.a */ = {
|
832341B51AAA6A8300B99B32 /* libRCTText.a */ = {
|
||||||
isa = PBXReferenceProxy;
|
isa = PBXReferenceProxy;
|
||||||
fileType = archive.ar;
|
fileType = archive.ar;
|
||||||
|
@ -1434,6 +1481,7 @@
|
||||||
"$(SRCROOT)/../node_modules/react-native-image-picker/ios",
|
"$(SRCROOT)/../node_modules/react-native-image-picker/ios",
|
||||||
"$(SRCROOT)/../node_modules/react-native-navigation/ios/**",
|
"$(SRCROOT)/../node_modules/react-native-navigation/ios/**",
|
||||||
"$(SRCROOT)/../node_modules/react-native-autogrow-textinput/ios",
|
"$(SRCROOT)/../node_modules/react-native-autogrow-textinput/ios",
|
||||||
|
"$(SRCROOT)/../node_modules/react-native-video/ios",
|
||||||
);
|
);
|
||||||
INFOPLIST_FILE = RocketChatRNTests/Info.plist;
|
INFOPLIST_FILE = RocketChatRNTests/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||||
|
@ -1442,6 +1490,8 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||||
|
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||||
|
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||||
);
|
);
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-ObjC",
|
"-ObjC",
|
||||||
|
@ -1468,6 +1518,7 @@
|
||||||
"$(SRCROOT)/../node_modules/react-native-image-picker/ios",
|
"$(SRCROOT)/../node_modules/react-native-image-picker/ios",
|
||||||
"$(SRCROOT)/../node_modules/react-native-navigation/ios/**",
|
"$(SRCROOT)/../node_modules/react-native-navigation/ios/**",
|
||||||
"$(SRCROOT)/../node_modules/react-native-autogrow-textinput/ios",
|
"$(SRCROOT)/../node_modules/react-native-autogrow-textinput/ios",
|
||||||
|
"$(SRCROOT)/../node_modules/react-native-video/ios",
|
||||||
);
|
);
|
||||||
INFOPLIST_FILE = RocketChatRNTests/Info.plist;
|
INFOPLIST_FILE = RocketChatRNTests/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||||
|
@ -1476,6 +1527,8 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||||
|
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||||
|
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||||
);
|
);
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-ObjC",
|
"-ObjC",
|
||||||
|
@ -1507,6 +1560,7 @@
|
||||||
"$(SRCROOT)/../node_modules/react-native-navigation/ios/**",
|
"$(SRCROOT)/../node_modules/react-native-navigation/ios/**",
|
||||||
"$(SRCROOT)/../node_modules/react-native-autogrow-textinput/ios",
|
"$(SRCROOT)/../node_modules/react-native-autogrow-textinput/ios",
|
||||||
"$(SRCROOT)/../node_modules/react-native/Libraries/PushNotificationIOS/RCTPushNotification.xcodeproj/**",
|
"$(SRCROOT)/../node_modules/react-native/Libraries/PushNotificationIOS/RCTPushNotification.xcodeproj/**",
|
||||||
|
"$(SRCROOT)/../node_modules/react-native-video/ios",
|
||||||
);
|
);
|
||||||
INFOPLIST_FILE = RocketChatRN/Info.plist;
|
INFOPLIST_FILE = RocketChatRN/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||||
|
@ -1543,6 +1597,7 @@
|
||||||
"$(SRCROOT)/../node_modules/react-native-navigation/ios/**",
|
"$(SRCROOT)/../node_modules/react-native-navigation/ios/**",
|
||||||
"$(SRCROOT)/../node_modules/react-native-autogrow-textinput/ios",
|
"$(SRCROOT)/../node_modules/react-native-autogrow-textinput/ios",
|
||||||
"$(SRCROOT)/../node_modules/react-native/Libraries/PushNotificationIOS/RCTPushNotification.xcodeproj/**",
|
"$(SRCROOT)/../node_modules/react-native/Libraries/PushNotificationIOS/RCTPushNotification.xcodeproj/**",
|
||||||
|
"$(SRCROOT)/../node_modules/react-native-video/ios",
|
||||||
);
|
);
|
||||||
INFOPLIST_FILE = RocketChatRN/Info.plist;
|
INFOPLIST_FILE = RocketChatRN/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||||
|
@ -1582,6 +1637,7 @@
|
||||||
"$(SRCROOT)/../node_modules/react-native-image-picker/ios",
|
"$(SRCROOT)/../node_modules/react-native-image-picker/ios",
|
||||||
"$(SRCROOT)/../node_modules/react-native-navigation/ios/**",
|
"$(SRCROOT)/../node_modules/react-native-navigation/ios/**",
|
||||||
"$(SRCROOT)/../node_modules/react-native-autogrow-textinput/ios",
|
"$(SRCROOT)/../node_modules/react-native-autogrow-textinput/ios",
|
||||||
|
"$(SRCROOT)/../node_modules/react-native-video/ios",
|
||||||
);
|
);
|
||||||
INFOPLIST_FILE = "RocketChatRN-tvOS/Info.plist";
|
INFOPLIST_FILE = "RocketChatRN-tvOS/Info.plist";
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||||
|
@ -1589,6 +1645,8 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||||
|
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||||
|
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||||
);
|
);
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-ObjC",
|
"-ObjC",
|
||||||
|
@ -1625,6 +1683,7 @@
|
||||||
"$(SRCROOT)/../node_modules/react-native-image-picker/ios",
|
"$(SRCROOT)/../node_modules/react-native-image-picker/ios",
|
||||||
"$(SRCROOT)/../node_modules/react-native-navigation/ios/**",
|
"$(SRCROOT)/../node_modules/react-native-navigation/ios/**",
|
||||||
"$(SRCROOT)/../node_modules/react-native-autogrow-textinput/ios",
|
"$(SRCROOT)/../node_modules/react-native-autogrow-textinput/ios",
|
||||||
|
"$(SRCROOT)/../node_modules/react-native-video/ios",
|
||||||
);
|
);
|
||||||
INFOPLIST_FILE = "RocketChatRN-tvOS/Info.plist";
|
INFOPLIST_FILE = "RocketChatRN-tvOS/Info.plist";
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||||
|
@ -1632,6 +1691,8 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||||
|
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||||
|
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||||
);
|
);
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-ObjC",
|
"-ObjC",
|
||||||
|
@ -1663,6 +1724,8 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||||
|
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||||
|
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.RocketChatRN-tvOSTests";
|
PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.RocketChatRN-tvOSTests";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
@ -1690,6 +1753,8 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||||
|
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||||
|
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.RocketChatRN-tvOSTests";
|
PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.RocketChatRN-tvOSTests";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -28,7 +28,6 @@
|
||||||
"react-native-action-button": "^2.8.3",
|
"react-native-action-button": "^2.8.3",
|
||||||
"react-native-actionsheet": "^2.3.0",
|
"react-native-actionsheet": "^2.3.0",
|
||||||
"react-native-animatable": "^1.2.4",
|
"react-native-animatable": "^1.2.4",
|
||||||
"react-native-card-view": "0.0.3",
|
|
||||||
"react-native-easy-markdown": "git+https://github.com/lappalj4/react-native-easy-markdown.git",
|
"react-native-easy-markdown": "git+https://github.com/lappalj4/react-native-easy-markdown.git",
|
||||||
"react-native-fetch-blob": "^0.10.8",
|
"react-native-fetch-blob": "^0.10.8",
|
||||||
"react-native-image-picker": "^0.26.7",
|
"react-native-image-picker": "^0.26.7",
|
||||||
|
@ -39,9 +38,12 @@
|
||||||
"react-native-modal": "^4.1.1",
|
"react-native-modal": "^4.1.1",
|
||||||
"react-native-optimized-flatlist": "^1.0.3",
|
"react-native-optimized-flatlist": "^1.0.3",
|
||||||
"react-native-push-notification": "^3.0.1",
|
"react-native-push-notification": "^3.0.1",
|
||||||
|
"react-native-slider": "^0.11.0",
|
||||||
"react-native-svg": "^6.0.0",
|
"react-native-svg": "^6.0.0",
|
||||||
"react-native-svg-image": "^2.0.1",
|
"react-native-svg-image": "^2.0.1",
|
||||||
"react-native-vector-icons": "^4.4.2",
|
"react-native-vector-icons": "^4.4.2",
|
||||||
|
"react-native-video": "^2.0.0",
|
||||||
|
"react-native-video-controls": "^2.0.0",
|
||||||
"react-native-zeroconf": "^0.8.3",
|
"react-native-zeroconf": "^0.8.3",
|
||||||
"react-navigation": "^1.0.0-beta.19",
|
"react-navigation": "^1.0.0-beta.19",
|
||||||
"react-redux": "^5.0.6",
|
"react-redux": "^5.0.6",
|
||||||
|
|
Loading…
Reference in New Issue