Link Previews (#890)
* Link previews, Image previews and YouTube * Install cocoapods dependencies
This commit is contained in:
parent
6e1d351a73
commit
7aebcbd52e
24 changed files with 1197 additions and 208 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -69,3 +69,7 @@ ios/sentry.properties
|
|||
|
||||
# Testing
|
||||
.nyc_output
|
||||
|
||||
# Pods
|
||||
.podinstall
|
||||
ios/Pods/
|
||||
|
|
|
|||
15
Makefile
15
Makefile
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
ios_target := $(filter-out build-ios,$(MAKECMDGOALS))
|
||||
android_target := $(filter-out build-android,$(MAKECMDGOALS))
|
||||
POD := $(shell command -v pod 2> /dev/null)
|
||||
|
||||
.yarninstall: package.json
|
||||
@if ! [ $(shell command -v yarn 2> /dev/null) ]; then \
|
||||
|
|
@ -16,7 +17,15 @@ android_target := $(filter-out build-android,$(MAKECMDGOALS))
|
|||
|
||||
yarn install --pure-lockfile
|
||||
|
||||
touch $@
|
||||
@touch $@
|
||||
|
||||
.podinstall:
|
||||
ifdef POD
|
||||
@echo Getting CocoaPods dependencies;
|
||||
@cd ios && pod install;
|
||||
endif
|
||||
|
||||
@touch $@
|
||||
|
||||
BASE_ASSETS = $(shell find assets/base -type d) $(shell find assets/base -type f -name '*')
|
||||
OVERRIDE_ASSETS = $(shell find assets/override -type d 2> /dev/null) $(shell find assets/override -type f -name '*' 2> /dev/null)
|
||||
|
|
@ -30,7 +39,7 @@ dist/assets: $(BASE_ASSETS) $(OVERRIDE_ASSETS)
|
|||
|
||||
node scripts/make-dist-assets.js
|
||||
|
||||
pre-run: .yarninstall dist/assets
|
||||
pre-run: | .yarninstall .podinstall dist/assets
|
||||
|
||||
run: run-ios
|
||||
|
||||
|
|
@ -89,8 +98,10 @@ clean:
|
|||
yarn cache clean
|
||||
rm -rf node_modules
|
||||
rm -f .yarninstall
|
||||
rm -f .podinstall
|
||||
rm -rf dist
|
||||
rm -rf ios/build
|
||||
rm -rf ios/Pods
|
||||
rm -rf android/app/build
|
||||
|
||||
post-install:
|
||||
|
|
|
|||
67
NOTICE.txt
67
NOTICE.txt
|
|
@ -1378,3 +1378,70 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---
|
||||
|
||||
## react-native-youtube
|
||||
|
||||
This product contains 'react-native-youtube', A <YouTube /> component for React Native.
|
||||
|
||||
* HOMEPAGE:
|
||||
* https://github.com/inProgress-team/react-native-youtube
|
||||
|
||||
* LICENSE:
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Param Aggarwal
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
---
|
||||
|
||||
## youtube-video-id
|
||||
|
||||
This product contains 'youtube-video-id', Extracts the YouTube video ID from a url or string.
|
||||
|
||||
* HOMEPAGE:
|
||||
* https://github.com/remarkablemark/youtube-video-id
|
||||
|
||||
* LICENSE:
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2016 Menglin "Mark" Xu <mark@remarkablemark.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
|
|
|||
|
|
@ -152,6 +152,7 @@ android {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
compile project(':react-native-youtube')
|
||||
compile project(':react-native-sentry')
|
||||
compile project(':react-native-exception-handler')
|
||||
compile project(':react-native-fetch-blob')
|
||||
|
|
@ -173,6 +174,13 @@ dependencies {
|
|||
compile project(':react-native-svg')
|
||||
compile project(':react-native-local-auth')
|
||||
compile project(':jail-monkey')
|
||||
|
||||
// For animated GIF support
|
||||
compile 'com.facebook.fresco:animated-base-support:1.0.1'
|
||||
// For WebP support, including animated WebP
|
||||
compile 'com.facebook.fresco:animated-gif:1.0.1'
|
||||
compile 'com.facebook.fresco:animated-webp:1.0.1'
|
||||
compile 'com.facebook.fresco:webpsupport:1.0.1'
|
||||
}
|
||||
|
||||
// Run this once to be able to run the application with BUCK
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import android.content.Context;
|
|||
import android.os.Bundle;
|
||||
|
||||
import com.facebook.react.ReactApplication;
|
||||
import com.inprogress.reactnativeyoutube.ReactNativeYouTube;
|
||||
import io.sentry.RNSentryPackage;
|
||||
import com.masteratul.exceptionhandler.ReactNativeExceptionHandlerPackage;
|
||||
import com.RNFetchBlob.RNFetchBlobPackage;
|
||||
|
|
@ -64,7 +65,8 @@ public class MainApplication extends NavigationApplication implements INotificat
|
|||
new RNFetchBlobPackage(),
|
||||
new MattermostManagedPackage(),
|
||||
new RNSentryPackage(this),
|
||||
new ReactNativeExceptionHandlerPackage()
|
||||
new ReactNativeExceptionHandlerPackage(),
|
||||
new ReactNativeYouTube()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
rootProject.name = 'Mattermost'
|
||||
include ':react-native-youtube'
|
||||
project(':react-native-youtube').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-youtube/android')
|
||||
include ':react-native-sentry'
|
||||
project(':react-native-sentry').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-sentry/android')
|
||||
include ':react-native-exception-handler'
|
||||
|
|
|
|||
28
app/components/post_attachment_opengraph/index.js
Normal file
28
app/components/post_attachment_opengraph/index.js
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import {connect} from 'react-redux';
|
||||
import {bindActionCreators} from 'redux';
|
||||
|
||||
import {getOpenGraphMetadata} from 'mattermost-redux/actions/posts';
|
||||
|
||||
import {getTheme} from 'app/selectors/preferences';
|
||||
|
||||
import PostAttachmentOpenGraph from './post_attachment_opengraph';
|
||||
|
||||
function mapStateToProps(state, ownProps) {
|
||||
return {
|
||||
...ownProps,
|
||||
theme: getTheme(state)
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return {
|
||||
actions: bindActionCreators({
|
||||
getOpenGraphMetadata
|
||||
}, dispatch)
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(PostAttachmentOpenGraph);
|
||||
|
|
@ -0,0 +1,252 @@
|
|||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import React, {PureComponent} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
Dimensions,
|
||||
Image,
|
||||
Linking,
|
||||
PixelRatio,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
View
|
||||
} from 'react-native';
|
||||
|
||||
import {getNearestPoint} from 'app/utils/opengraph';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
|
||||
|
||||
const LARGE_IMAGE_MIN_WIDTH = 150;
|
||||
const LARGE_IMAGE_MIN_RATIO = (16 / 9);
|
||||
const MAX_IMAGE_HEIGHT = 150;
|
||||
const THUMBNAIL_SIZE = 75;
|
||||
|
||||
export default class PostAttachmentOpenGraph extends PureComponent {
|
||||
static propTypes = {
|
||||
actions: PropTypes.shape({
|
||||
getOpenGraphMetadata: PropTypes.func.isRequired
|
||||
}).isRequired,
|
||||
link: PropTypes.string.isRequired,
|
||||
openGraphData: PropTypes.object,
|
||||
theme: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
imageLoaded: false,
|
||||
hasLargeImage: false
|
||||
};
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
this.fetchData(this.props.link, this.props.openGraphData);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (nextProps.link !== this.props.link) {
|
||||
this.setState({imageLoaded: false});
|
||||
this.fetchData(nextProps.link, nextProps.openGraphData);
|
||||
}
|
||||
}
|
||||
|
||||
calculateLargeImageDimensions = (width, height) => {
|
||||
const {width: deviceWidth} = Dimensions.get('window');
|
||||
let maxHeight = MAX_IMAGE_HEIGHT;
|
||||
let maxWidth = deviceWidth - 88;
|
||||
|
||||
if (height <= MAX_IMAGE_HEIGHT) {
|
||||
maxHeight = height;
|
||||
} else {
|
||||
maxHeight = (height / width) * maxWidth;
|
||||
if (maxHeight > MAX_IMAGE_HEIGHT) {
|
||||
maxHeight = MAX_IMAGE_HEIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
if (height > width) {
|
||||
maxWidth = (width / height) * maxHeight;
|
||||
}
|
||||
|
||||
return {width: maxWidth, height: maxHeight};
|
||||
};
|
||||
|
||||
calculateSmallImageDimensions = (width, height) => {
|
||||
const {width: deviceWidth} = Dimensions.get('window');
|
||||
const offset = deviceWidth - 170;
|
||||
|
||||
let ratio;
|
||||
let maxWidth;
|
||||
let maxHeight;
|
||||
|
||||
if (width >= height) {
|
||||
ratio = width / height;
|
||||
maxWidth = THUMBNAIL_SIZE;
|
||||
maxHeight = PixelRatio.roundToNearestPixel(maxWidth / ratio);
|
||||
} else {
|
||||
ratio = height / width;
|
||||
maxHeight = THUMBNAIL_SIZE;
|
||||
maxWidth = PixelRatio.roundToNearestPixel(maxHeight / ratio);
|
||||
}
|
||||
|
||||
return {width: maxWidth, height: maxHeight, offset};
|
||||
};
|
||||
|
||||
fetchData(url, openGraphData) {
|
||||
if (!openGraphData) {
|
||||
this.props.actions.getOpenGraphMetadata(url);
|
||||
}
|
||||
}
|
||||
|
||||
getBestImageUrl(data) {
|
||||
if (!data.images) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const bestDimensions = {
|
||||
width: Dimensions.get('window').width - 88,
|
||||
height: MAX_IMAGE_HEIGHT
|
||||
};
|
||||
const bestImage = getNearestPoint(bestDimensions, data.images, 'width', 'height');
|
||||
return bestImage.secure_url || bestImage.url;
|
||||
}
|
||||
|
||||
getImageSize = (imageUrl) => {
|
||||
if (!this.state.imageLoaded) {
|
||||
Image.getSize(imageUrl, (width, height) => {
|
||||
const {hasLargeImage} = this.state;
|
||||
const imageRatio = width / height;
|
||||
|
||||
let isLarge = false;
|
||||
let dimensions;
|
||||
if (width >= LARGE_IMAGE_MIN_WIDTH && imageRatio >= LARGE_IMAGE_MIN_RATIO && !hasLargeImage) {
|
||||
isLarge = true;
|
||||
dimensions = this.calculateLargeImageDimensions(width, height);
|
||||
} else {
|
||||
dimensions = this.calculateSmallImageDimensions(width, height);
|
||||
}
|
||||
this.setState({
|
||||
...dimensions,
|
||||
hasLargeImage: isLarge,
|
||||
imageLoaded: true
|
||||
});
|
||||
}, () => null);
|
||||
}
|
||||
};
|
||||
|
||||
goToLink = () => {
|
||||
Linking.openURL(this.props.link);
|
||||
};
|
||||
|
||||
render() {
|
||||
const {openGraphData, theme} = this.props;
|
||||
const {hasLargeImage, height, imageLoaded, offset, width} = this.state;
|
||||
|
||||
if (!openGraphData || !openGraphData.description) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const style = getStyleSheet(theme);
|
||||
const imageUrl = this.getBestImageUrl(openGraphData);
|
||||
const isThumbnail = !hasLargeImage && imageLoaded;
|
||||
if (imageUrl) {
|
||||
this.getImageSize(imageUrl);
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={style.container}>
|
||||
<View style={style.flex}>
|
||||
<Text
|
||||
style={style.siteTitle}
|
||||
numberOfLines={1}
|
||||
ellipsizeMode='tail'
|
||||
>
|
||||
{openGraphData.site_name}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={style.wrapper}>
|
||||
<TouchableOpacity
|
||||
style={isThumbnail ? {width: offset} : style.flex}
|
||||
onPress={this.goToLink}
|
||||
>
|
||||
<Text
|
||||
style={style.siteSubtitle}
|
||||
numberOfLines={3}
|
||||
ellipsizeMode='tail'
|
||||
>
|
||||
{openGraphData.title}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
{isThumbnail &&
|
||||
<View style={style.thumbnail}>
|
||||
<Image
|
||||
style={[style.image, {width, height}]}
|
||||
source={{uri: imageUrl}}
|
||||
resizeMode='cover'
|
||||
/>
|
||||
</View>
|
||||
}
|
||||
</View>
|
||||
<View style={style.flex}>
|
||||
<Text
|
||||
style={style.siteDescription}
|
||||
numberOfLines={5}
|
||||
ellipsizeMode='tail'
|
||||
>
|
||||
{openGraphData.description}
|
||||
</Text>
|
||||
</View>
|
||||
{hasLargeImage && imageLoaded &&
|
||||
<Image
|
||||
style={[style.image, {width, height}]}
|
||||
source={{uri: imageUrl}}
|
||||
resizeMode='cover'
|
||||
/>
|
||||
}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
||||
return {
|
||||
container: {
|
||||
flex: 1,
|
||||
borderColor: changeOpacity(theme.centerChannelColor, 0.2),
|
||||
borderWidth: 1,
|
||||
marginTop: 10,
|
||||
padding: 10
|
||||
},
|
||||
flex: {
|
||||
flex: 1
|
||||
},
|
||||
wrapper: {
|
||||
flex: 1,
|
||||
flexDirection: 'row'
|
||||
},
|
||||
siteTitle: {
|
||||
fontSize: 12,
|
||||
color: changeOpacity(theme.centerChannelColor, 0.5),
|
||||
marginBottom: 10
|
||||
},
|
||||
siteSubtitle: {
|
||||
fontSize: 14,
|
||||
color: theme.linkColor,
|
||||
marginBottom: 10
|
||||
},
|
||||
siteDescription: {
|
||||
fontSize: 13,
|
||||
color: changeOpacity(theme.centerChannelColor, 0.7),
|
||||
marginBottom: 10
|
||||
},
|
||||
image: {
|
||||
borderRadius: 3
|
||||
},
|
||||
thumbnail: {
|
||||
flex: 1,
|
||||
alignItems: 'flex-end',
|
||||
justifyContent: 'flex-start'
|
||||
}
|
||||
};
|
||||
});
|
||||
|
|
@ -20,7 +20,7 @@ function mapStateToProps(state, ownProps) {
|
|||
|
||||
return {
|
||||
...ownProps,
|
||||
attachments: post.props && post.props.attachments,
|
||||
postProps: post.props || {},
|
||||
fileIds: post.file_ids,
|
||||
hasBeenDeleted: post.state === Posts.POST_DELETED,
|
||||
hasReactions: post.has_reactions,
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@ import FileAttachmentList from 'app/components/file_attachment_list';
|
|||
import FormattedText from 'app/components/formatted_text';
|
||||
import Markdown from 'app/components/markdown';
|
||||
import OptionsContext from 'app/components/options_context';
|
||||
import SlackAttachments from 'app/components/slack_attachments';
|
||||
|
||||
import PostBodyAdditionalContent from 'app/components/post_body_additional_content';
|
||||
|
||||
import {emptyFunction} from 'app/utils/general';
|
||||
import {getMarkdownTextStyles, getMarkdownBlockStyles} from 'app/utils/markdown';
|
||||
|
|
@ -29,7 +30,6 @@ class PostBody extends PureComponent {
|
|||
flagPost: PropTypes.func.isRequired,
|
||||
unflagPost: PropTypes.func.isRequired
|
||||
}).isRequired,
|
||||
attachments: PropTypes.array,
|
||||
canDelete: PropTypes.bool,
|
||||
canEdit: PropTypes.bool,
|
||||
fileIds: PropTypes.array,
|
||||
|
|
@ -49,6 +49,7 @@ class PostBody extends PureComponent {
|
|||
onPostEdit: PropTypes.func,
|
||||
onPress: PropTypes.func,
|
||||
postId: PropTypes.string.isRequired,
|
||||
postProps: PropTypes.object,
|
||||
renderReplyBar: PropTypes.func,
|
||||
theme: PropTypes.object,
|
||||
toggleSelected: PropTypes.func
|
||||
|
|
@ -123,25 +124,6 @@ class PostBody extends PureComponent {
|
|||
return attachments;
|
||||
}
|
||||
|
||||
renderSlackAttachments = (baseStyle, blockStyles, textStyles) => {
|
||||
const {attachments, navigator, theme} = this.props;
|
||||
|
||||
if (attachments && attachments.length) {
|
||||
return (
|
||||
<SlackAttachments
|
||||
attachments={attachments}
|
||||
baseTextStyle={baseStyle}
|
||||
blockStyles={blockStyles}
|
||||
navigator={navigator}
|
||||
textStyles={textStyles}
|
||||
theme={theme}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
canDelete,
|
||||
|
|
@ -161,6 +143,7 @@ class PostBody extends PureComponent {
|
|||
onPostEdit,
|
||||
onPress,
|
||||
postId,
|
||||
postProps,
|
||||
renderReplyBar,
|
||||
theme,
|
||||
toggleSelected
|
||||
|
|
@ -201,6 +184,7 @@ class PostBody extends PureComponent {
|
|||
});
|
||||
}
|
||||
|
||||
let body;
|
||||
let messageComponent;
|
||||
if (hasBeenDeleted) {
|
||||
messageComponent = (
|
||||
|
|
@ -210,6 +194,7 @@ class PostBody extends PureComponent {
|
|||
defaultMessage='(message deleted)'
|
||||
/>
|
||||
);
|
||||
body = (<View>{messageComponent}</View>);
|
||||
} else if (message.length) {
|
||||
messageComponent = (
|
||||
<View style={{flexDirection: 'row'}}>
|
||||
|
|
@ -229,38 +214,53 @@ class PostBody extends PureComponent {
|
|||
);
|
||||
}
|
||||
|
||||
let body;
|
||||
if (isSearchResult) {
|
||||
body = (
|
||||
<TouchableHighlight
|
||||
onHideUnderlay={this.handleHideUnderlay}
|
||||
onLongPress={this.show}
|
||||
onPress={onPress}
|
||||
onShowUnderlay={this.handleShowUnderlay}
|
||||
underlayColor='transparent'
|
||||
>
|
||||
<View>
|
||||
if (!hasBeenDeleted) {
|
||||
if (isSearchResult) {
|
||||
body = (
|
||||
<TouchableHighlight
|
||||
onHideUnderlay={this.handleHideUnderlay}
|
||||
onLongPress={this.show}
|
||||
onPress={onPress}
|
||||
onShowUnderlay={this.handleShowUnderlay}
|
||||
underlayColor='transparent'
|
||||
>
|
||||
<View>
|
||||
{messageComponent}
|
||||
<PostBodyAdditionalContent
|
||||
baseTextStyle={messageStyle}
|
||||
blockStyles={blockStyles}
|
||||
navigator={navigator}
|
||||
message={message}
|
||||
postProps={postProps}
|
||||
textStyles={textStyles}
|
||||
/>
|
||||
{this.renderFileAttachments()}
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
);
|
||||
} else {
|
||||
body = (
|
||||
<OptionsContext
|
||||
actions={actions}
|
||||
ref='options'
|
||||
onPress={onPress}
|
||||
toggleSelected={toggleSelected}
|
||||
cancelText={formatMessage({id: 'channel_modal.cancel', defaultMessage: 'Cancel'})}
|
||||
>
|
||||
{messageComponent}
|
||||
{this.renderSlackAttachments(messageStyle, blockStyles, textStyles)}
|
||||
<PostBodyAdditionalContent
|
||||
baseTextStyle={messageStyle}
|
||||
blockStyles={blockStyles}
|
||||
message={message}
|
||||
navigator={navigator}
|
||||
postProps={postProps}
|
||||
textStyles={textStyles}
|
||||
/>
|
||||
{this.renderFileAttachments()}
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
);
|
||||
} else {
|
||||
body = (
|
||||
<OptionsContext
|
||||
actions={actions}
|
||||
ref='options'
|
||||
onPress={onPress}
|
||||
toggleSelected={toggleSelected}
|
||||
cancelText={formatMessage({id: 'channel_modal.cancel', defaultMessage: 'Cancel'})}
|
||||
>
|
||||
{messageComponent}
|
||||
{this.renderSlackAttachments(messageStyle, blockStyles, textStyles)}
|
||||
{this.renderFileAttachments()}
|
||||
{hasReactions && <Reactions postId={postId}/>}
|
||||
</OptionsContext>
|
||||
);
|
||||
{hasReactions && <Reactions postId={postId}/>}
|
||||
</OptionsContext>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
|||
35
app/components/post_body_additional_content/index.js
Normal file
35
app/components/post_body_additional_content/index.js
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import {connect} from 'react-redux';
|
||||
|
||||
import {Preferences} from 'mattermost-redux/constants';
|
||||
import {getConfig} from 'mattermost-redux/selectors/entities/general';
|
||||
import {getOpenGraphMetadataForUrl} from 'mattermost-redux/selectors/entities/posts';
|
||||
import {getBool} from 'mattermost-redux/selectors/entities/preferences';
|
||||
|
||||
import {ViewTypes} from 'app/constants';
|
||||
import {getTheme} from 'app/selectors/preferences';
|
||||
|
||||
import {extractFirstLink} from 'app/utils/url';
|
||||
import PostBodyAdditionalContent from './post_body_additional_content';
|
||||
|
||||
function mapStateToProps(state, ownProps) {
|
||||
const config = getConfig(state);
|
||||
const previewsEnabled = getBool(state, Preferences.CATEGORY_ADVANCED_SETTINGS, `${ViewTypes.FEATURE_TOGGLE_PREFIX}${ViewTypes.EMBED_PREVIEW}`);
|
||||
const link = extractFirstLink(ownProps.message);
|
||||
|
||||
return {
|
||||
...ownProps,
|
||||
config,
|
||||
link,
|
||||
openGraphData: getOpenGraphMetadataForUrl(state, link),
|
||||
showLinkPreviews: previewsEnabled && config.EnableLinkPreviews === 'true',
|
||||
theme: getTheme(state)
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(PostBodyAdditionalContent);
|
||||
|
|
@ -0,0 +1,280 @@
|
|||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import React, {PureComponent} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
Dimensions,
|
||||
Image,
|
||||
Linking,
|
||||
Platform,
|
||||
StyleSheet,
|
||||
TouchableWithoutFeedback,
|
||||
View
|
||||
} from 'react-native';
|
||||
import Orientation from 'react-native-orientation';
|
||||
import {YouTubeStandaloneAndroid, YouTubeStandaloneIOS} from 'react-native-youtube';
|
||||
import youTubeVideoId from 'youtube-video-id';
|
||||
import youtubePlayIcon from 'assets/images/icons/youtube-play-icon.png';
|
||||
|
||||
import PostAttachmentOpenGraph from 'app/components/post_attachment_opengraph';
|
||||
import SlackAttachments from 'app/components/slack_attachments';
|
||||
import CustomPropTypes from 'app/constants/custom_prop_types';
|
||||
import {isImageLink, isYoutubeLink} from 'app/utils/url';
|
||||
|
||||
const MAX_IMAGE_HEIGHT = 150;
|
||||
|
||||
export default class PostBodyAdditionalContent extends PureComponent {
|
||||
static propTypes = {
|
||||
baseTextStyle: CustomPropTypes.Style,
|
||||
blockStyles: PropTypes.object,
|
||||
config: PropTypes.object,
|
||||
link: PropTypes.string,
|
||||
message: PropTypes.string.isRequired,
|
||||
navigator: PropTypes.object.isRequired,
|
||||
openGraphData: PropTypes.object,
|
||||
postProps: PropTypes.object.isRequired,
|
||||
showLinkPreviews: PropTypes.bool.isRequired,
|
||||
textStyles: PropTypes.object,
|
||||
theme: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
linkLoadError: false,
|
||||
linkLoaded: false
|
||||
};
|
||||
|
||||
this.mounted = false;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.mounted = true;
|
||||
this.getImageSize();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.mounted = false;
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (nextProps.message !== this.props.message) {
|
||||
this.setState({
|
||||
linkLoadError: false,
|
||||
linkLoaded: false
|
||||
}, () => {
|
||||
this.getImageSize();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
calculateDimensions = (width, height) => {
|
||||
const {width: deviceWidth} = Dimensions.get('window');
|
||||
let maxHeight = MAX_IMAGE_HEIGHT;
|
||||
let maxWidth = deviceWidth - 68;
|
||||
|
||||
if (height <= MAX_IMAGE_HEIGHT) {
|
||||
maxHeight = height;
|
||||
} else {
|
||||
maxHeight = (height / width) * maxWidth;
|
||||
if (maxHeight > MAX_IMAGE_HEIGHT) {
|
||||
maxHeight = MAX_IMAGE_HEIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
if (height > width) {
|
||||
maxWidth = (width / height) * maxHeight;
|
||||
}
|
||||
|
||||
return {width: maxWidth, height: maxHeight};
|
||||
};
|
||||
|
||||
generateStaticEmbed = (isYouTube) => {
|
||||
if (isYouTube) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const {link, openGraphData, showLinkPreviews} = this.props;
|
||||
const attachments = this.getSlackAttachment();
|
||||
if (attachments) {
|
||||
return attachments;
|
||||
}
|
||||
|
||||
if (link && showLinkPreviews) {
|
||||
return (
|
||||
<PostAttachmentOpenGraph
|
||||
link={link}
|
||||
openGraphData={openGraphData}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
getImageSize = () => {
|
||||
const {link} = this.props;
|
||||
const {linkLoaded} = this.state;
|
||||
|
||||
let imageUrl;
|
||||
if (isImageLink(link)) {
|
||||
imageUrl = link;
|
||||
} else if (isYoutubeLink(link)) {
|
||||
const videoId = youTubeVideoId(link);
|
||||
imageUrl = `https://i.ytimg.com/vi/${videoId}/hqdefault.jpg`;
|
||||
}
|
||||
|
||||
if (imageUrl && !linkLoaded) {
|
||||
Image.getSize(imageUrl, (width, height) => {
|
||||
if (!this.mounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
const dimensions = this.calculateDimensions(width, height);
|
||||
this.setState({...dimensions, linkLoaded: true});
|
||||
}, () => null);
|
||||
}
|
||||
};
|
||||
|
||||
getSlackAttachment = () => {
|
||||
const {
|
||||
postProps,
|
||||
baseTextStyle,
|
||||
blockStyles,
|
||||
navigator,
|
||||
textStyles,
|
||||
theme
|
||||
} = this.props;
|
||||
const {attachments} = postProps;
|
||||
|
||||
if (attachments && attachments.length) {
|
||||
return (
|
||||
<SlackAttachments
|
||||
attachments={attachments}
|
||||
baseTextStyle={baseTextStyle}
|
||||
blockStyles={blockStyles}
|
||||
navigator={navigator}
|
||||
textStyles={textStyles}
|
||||
theme={theme}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
generateToggleableEmbed = (isImage, isYouTube) => {
|
||||
const {link} = this.props;
|
||||
const {width, height} = this.state;
|
||||
|
||||
if (link) {
|
||||
if (isYouTube) {
|
||||
const videoId = youTubeVideoId(link);
|
||||
const imgUrl = `https://i.ytimg.com/vi/${videoId}/hqdefault.jpg`;
|
||||
|
||||
return (
|
||||
<TouchableWithoutFeedback
|
||||
style={styles.imageContainer}
|
||||
{...this.responder}
|
||||
onPress={this.playYouTubeVideo}
|
||||
>
|
||||
<Image
|
||||
style={[styles.image, {width, height}]}
|
||||
source={{uri: imgUrl}}
|
||||
resizeMode={'cover'}
|
||||
onError={this.handleLinkLoadError}
|
||||
>
|
||||
<TouchableWithoutFeedback onPress={this.playYouTubeVideo}>
|
||||
<Image
|
||||
source={youtubePlayIcon}
|
||||
onPress={this.playYouTubeVideo}
|
||||
/>
|
||||
</TouchableWithoutFeedback>
|
||||
</Image>
|
||||
</TouchableWithoutFeedback>
|
||||
);
|
||||
}
|
||||
|
||||
if (isImage) {
|
||||
return (
|
||||
<View style={styles.imageContainer}>
|
||||
<Image
|
||||
style={[styles.image, {width, height}]}
|
||||
source={{uri: link}}
|
||||
resizeMode={'cover'}
|
||||
onError={this.handleLinkLoadError}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
playYouTubeVideo = () => {
|
||||
const {link} = this.props;
|
||||
const videoId = youTubeVideoId(link);
|
||||
|
||||
Orientation.unlockAllOrientations();
|
||||
if (Platform.OS === 'ios') {
|
||||
YouTubeStandaloneIOS.playVideo(videoId).then(() => {
|
||||
Orientation.lockToPortrait();
|
||||
});
|
||||
} else {
|
||||
const {config} = this.props;
|
||||
|
||||
if (config.GoogleDeveloperKey) {
|
||||
YouTubeStandaloneAndroid.playVideo({
|
||||
apiKey: config.GoogleDeveloperKey,
|
||||
videoId,
|
||||
autoplay: true
|
||||
}).then(() => {
|
||||
Orientation.lockToPortrait();
|
||||
});
|
||||
} else {
|
||||
Linking.openURL(link);
|
||||
Orientation.lockToPortrait();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
handleLinkLoadError = () => {
|
||||
this.setState({linkLoadError: true});
|
||||
};
|
||||
|
||||
render() {
|
||||
const {link, openGraphData} = this.props;
|
||||
const {linkLoaded, linkLoadError} = this.state;
|
||||
const isYouTube = isYoutubeLink(link);
|
||||
const isImage = isImageLink(link);
|
||||
const isOpenGraph = Boolean(openGraphData && openGraphData.description);
|
||||
|
||||
if ((isImage && !isOpenGraph && !linkLoadError) || isYouTube) {
|
||||
const embed = this.generateToggleableEmbed(isImage, isYouTube);
|
||||
if (embed && (linkLoaded || isYouTube)) {
|
||||
return embed;
|
||||
}
|
||||
}
|
||||
|
||||
return this.generateStaticEmbed(isYouTube);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
imageContainer: {
|
||||
alignItems: 'flex-start',
|
||||
flex: 1,
|
||||
justifyContent: 'flex-start',
|
||||
marginBottom: 6,
|
||||
marginTop: 10
|
||||
},
|
||||
image: {
|
||||
alignItems: 'center',
|
||||
borderRadius: 3,
|
||||
justifyContent: 'center',
|
||||
marginVertical: 1
|
||||
}
|
||||
});
|
||||
|
|
@ -54,5 +54,7 @@ const ViewTypes = keyMirror({
|
|||
|
||||
export default {
|
||||
...ViewTypes,
|
||||
POST_VISIBILITY_CHUNK_SIZE: Posts.POST_CHUNK_SIZE / 2
|
||||
POST_VISIBILITY_CHUNK_SIZE: Posts.POST_CHUNK_SIZE / 2,
|
||||
FEATURE_TOGGLE_PREFIX: 'feature_enabled_',
|
||||
EMBED_PREVIEW: 'embed_preview'
|
||||
};
|
||||
|
|
|
|||
23
app/utils/opengraph.js
Normal file
23
app/utils/opengraph.js
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
export function getDistanceBW2Points(point1, point2, xAttr = 'x', yAttr = 'y') {
|
||||
return Math.sqrt(Math.pow(point1[xAttr] - point2[xAttr], 2) + Math.pow(point1[yAttr] - point2[yAttr], 2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Funtion to return nearest point of given pivot point.
|
||||
* It return two points one nearest and other nearest but having both coorditanes smaller than the given point's coordinates.
|
||||
*/
|
||||
export function getNearestPoint(pivotPoint, points, xAttr = 'x', yAttr = 'y') {
|
||||
let nearestPoint = {};
|
||||
for (const point of points) {
|
||||
if (typeof nearestPoint[xAttr] === 'undefined' || typeof nearestPoint[yAttr] === 'undefined') {
|
||||
nearestPoint = point;
|
||||
} else if (getDistanceBW2Points(point, pivotPoint, xAttr, yAttr) < getDistanceBW2Points(nearestPoint, pivotPoint, xAttr, yAttr)) {
|
||||
// Check for bestImage
|
||||
nearestPoint = point;
|
||||
}
|
||||
}
|
||||
return nearestPoint;
|
||||
}
|
||||
|
|
@ -1,6 +1,9 @@
|
|||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
const ytRegex = /(?:http|https):\/\/(?:www\.|m\.)?(?:(?:youtube\.com\/(?:(?:v\/)|(?:(?:watch|embed\/watch)(?:\/|.*v=))|(?:embed\/)|(?:user\/[^/]+\/u\/[0-9]\/)))|(?:youtu\.be\/))([^#&?]*)/;
|
||||
const imgRegex = /.+\/(.+\.(?:jpg|gif|bmp|png|jpeg))(?:\?.*)?$/i;
|
||||
|
||||
export function isValidUrl(url = '') {
|
||||
const regex = /^https?:\/\//i;
|
||||
return regex.test(url);
|
||||
|
|
@ -13,3 +16,30 @@ export function stripTrailingSlashes(url = '') {
|
|||
export function removeProtocol(url = '') {
|
||||
return url.replace(/(^\w+:|^)\/\//, '');
|
||||
}
|
||||
|
||||
export function extractFirstLink(text) {
|
||||
const pattern = /(^|[\s\n]|<br\/?>)((?:https?|ftp):\/\/[-A-Z0-9+\u0026\u2019@#/%?=()~_|!:,.;]*[-A-Z0-9+\u0026@#/%=~()_|])/i;
|
||||
let inText = text;
|
||||
|
||||
// strip out code blocks
|
||||
inText = inText.replace(/`[^`]*`/g, '');
|
||||
|
||||
// strip out inline markdown images
|
||||
inText = inText.replace(/!\[[^\]]*]\([^)]*\)/g, '');
|
||||
|
||||
const match = pattern.exec(inText);
|
||||
if (match) {
|
||||
return match[0].trim();
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
export function isYoutubeLink(link) {
|
||||
return link.trim().match(ytRegex);
|
||||
}
|
||||
|
||||
export function isImageLink(link) {
|
||||
const match = link.trim().match(imgRegex);
|
||||
return Boolean(match && match[1]);
|
||||
}
|
||||
|
|
|
|||
BIN
assets/base/images/icons/youtube-play-icon.png
Normal file
BIN
assets/base/images/icons/youtube-play-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
|
|
@ -40,8 +40,10 @@
|
|||
420A7328E12C4B72AEF420CE /* Octicons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = EDC04CBCF81642219D199CBB /* Octicons.ttf */; };
|
||||
55C6561DDBBA45929D88B6D1 /* OpenSans-BoldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 32AC3D4EA79E44738A6E9766 /* OpenSans-BoldItalic.ttf */; };
|
||||
584837D6B55F405F908A2053 /* libBVLinearGradient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = ACC6B9FDC0AD45A6BFA4FBCD /* libBVLinearGradient.a */; };
|
||||
5CB86E9DFB94485CAA748DF3 /* YTPlayerView-iframe-player.html in Resources */ = {isa = PBXBuildFile; fileRef = 79CB6EBA24FE4ABFB0C155F0 /* YTPlayerView-iframe-player.html */; };
|
||||
5E1AF7B72B8D4A4E9E53FF9D /* FontAwesome.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 005346E5C0E542BFABAE1411 /* FontAwesome.ttf */; };
|
||||
5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */; };
|
||||
5F190C97C28E4E5E93D933C0 /* libRCTYouTube.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8EAB7CA059E14A73918789B6 /* libRCTYouTube.a */; };
|
||||
615D2E7805814A3A9B9C69EC /* libRNLocalAuth.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EE3EE4548D3F4A49B1274722 /* libRNLocalAuth.a */; };
|
||||
62A8448264674B4D95A5A7C2 /* OpenSans-Semibold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = C78A387124874496AD2C1466 /* OpenSans-Semibold.ttf */; };
|
||||
69AC753E496743BABB7A7124 /* OpenSans-SemiboldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0E617BF0F36D4E738F51D169 /* OpenSans-SemiboldItalic.ttf */; };
|
||||
|
|
@ -61,6 +63,7 @@
|
|||
895C9A56B94A45C1BAF568FE /* Entypo.ttf in Resources */ = {isa = PBXBuildFile; fileRef = AC6EB561E1F64C17A69D2FAD /* Entypo.ttf */; };
|
||||
9358B95F95184EE0A4DCE629 /* OpenSans-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D4B1B363C2414DA19C1AC521 /* OpenSans-Bold.ttf */; };
|
||||
A08D512E7ADC40CCAD055A9E /* OpenSans-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = BC977883E2624E05975CA65B /* OpenSans-Regular.ttf */; };
|
||||
A14B2A56A554E84DFE3D6580 /* libPods-Mattermost.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 65FD5EA57EBAE06106094B2F /* libPods-Mattermost.a */; };
|
||||
C035DB50ED2045F09923FFAE /* MaterialCommunityIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 04AA5E8EF3B54735A11E3B95 /* MaterialCommunityIcons.ttf */; };
|
||||
C337E8708D2845C6A8DBB47E /* Ionicons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 2DCFD31D3F4A4154822AB532 /* Ionicons.ttf */; };
|
||||
CB1B312483534997BEE7E65E /* libRNSentry.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2AE23B96BF7545B9A77C0C87 /* libRNSentry.a */; };
|
||||
|
|
@ -68,6 +71,7 @@
|
|||
DEBCF44F1F46413BB407D316 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 8606EB1EB7E349EF8248933E /* libz.tbd */; };
|
||||
F006936FC2884C24A1321FC0 /* MaterialIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 356C9186FA374641A00EB2EA /* MaterialIcons.ttf */; };
|
||||
F083DB472349411A8E6E7AAD /* OpenSans-LightItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = BE17F630DB5D41FD93F32D22 /* OpenSans-LightItalic.ttf */; };
|
||||
F23C99AA5FA10E457A76803A /* libPods-MattermostTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4246DC09024BB33A3E491E25 /* libPods-MattermostTests.a */; };
|
||||
FDEF24E9D9AB47728E11033B /* libRNPasscodeStatus.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 17A75F5A3D0D4A4A995DCD76 /* libRNPasscodeStatus.a */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
|
|
@ -366,6 +370,27 @@
|
|||
remoteGlobalIDString = 1BD725DA1CF77A8B005DBD79;
|
||||
remoteInfo = RNCookieManagerIOS;
|
||||
};
|
||||
7FA794EC1F61A1A500C02924 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = A2968536BEC74A4ABBB73BD9 /* RCTYouTube.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 8BDB9BC91B4289AE00EF9FEF;
|
||||
remoteInfo = RCTYouTube;
|
||||
};
|
||||
7FA795051F61A1A500C02924 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 9552041247E749308CE7B412 /* RNSentry.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 134814201AA4EA6300B7C361;
|
||||
remoteInfo = RNSentry;
|
||||
};
|
||||
7FA7950A1F61A1A500C02924 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 3B1E210BF3B649BBBF427977 /* ReactNativeExceptionHandler.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 134814201AA4EA6300B7C361;
|
||||
remoteInfo = ReactNativeExceptionHandler;
|
||||
};
|
||||
7FC200DE1EBB65100099331B /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 7FC200BC1EBB65100099331B /* ReactNativeNavigation.xcodeproj */;
|
||||
|
|
@ -387,20 +412,6 @@
|
|||
remoteGlobalIDString = 5DBEB1501B18CEA900B34395;
|
||||
remoteInfo = RNVectorIcons;
|
||||
};
|
||||
7FEB10851F6101090039A015 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 3B1E210BF3B649BBBF427977 /* ReactNativeExceptionHandler.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 134814201AA4EA6300B7C361;
|
||||
remoteInfo = ReactNativeExceptionHandler;
|
||||
};
|
||||
7FEB10901F61010A0039A015 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 9552041247E749308CE7B412 /* RNSentry.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 134814201AA4EA6300B7C361;
|
||||
remoteInfo = RNSentry;
|
||||
};
|
||||
832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;
|
||||
|
|
@ -459,8 +470,11 @@
|
|||
3647DF63D6764CF093375861 /* OpenSans-ExtraBold.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "OpenSans-ExtraBold.ttf"; path = "../assets/fonts/OpenSans-ExtraBold.ttf"; sourceTree = "<group>"; };
|
||||
3752184A1F4B9E980035444B /* RCTCameraRoll.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTCameraRoll.xcodeproj; path = "../node_modules/react-native/Libraries/CameraRoll/RCTCameraRoll.xcodeproj"; sourceTree = "<group>"; };
|
||||
37ABD3971F4CE13B001FDE6B /* ART.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ART.xcodeproj; path = "../node_modules/react-native/Libraries/ART/ART.xcodeproj"; sourceTree = "<group>"; };
|
||||
3820CC3BBC4B0129958555A9 /* Pods-MattermostTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MattermostTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-MattermostTests/Pods-MattermostTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
3B1E210BF3B649BBBF427977 /* ReactNativeExceptionHandler.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = ReactNativeExceptionHandler.xcodeproj; path = "../node_modules/react-native-exception-handler/ios/ReactNativeExceptionHandler.xcodeproj"; sourceTree = "<group>"; };
|
||||
41465DE822E9429EB8B90CB4 /* Pods-MattermostTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MattermostTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-MattermostTests/Pods-MattermostTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
41F3AFE83AAF4B74878AB78A /* OpenSans-Italic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "OpenSans-Italic.ttf"; path = "../assets/fonts/OpenSans-Italic.ttf"; sourceTree = "<group>"; };
|
||||
4246DC09024BB33A3E491E25 /* libPods-MattermostTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-MattermostTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
4A22BC320BA04E18A7F2A4E6 /* libReactNativeExceptionHandler.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libReactNativeExceptionHandler.a; sourceTree = "<group>"; };
|
||||
4B19E38FBCB94C57BB03B8E6 /* libRNFetchBlob.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNFetchBlob.a; sourceTree = "<group>"; };
|
||||
50ECB1D221E44F51B5690DF2 /* 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>"; };
|
||||
|
|
@ -468,9 +482,12 @@
|
|||
546CB0A5BB8F453890CBA559 /* RNFetchBlob.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNFetchBlob.xcodeproj; path = "../node_modules/react-native-fetch-blob/ios/RNFetchBlob.xcodeproj"; sourceTree = "<group>"; };
|
||||
5C3B95629BA74FB3A8377CB7 /* RCTOrientation.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RCTOrientation.xcodeproj; path = "../node_modules/react-native-orientation/iOS/RCTOrientation.xcodeproj"; sourceTree = "<group>"; };
|
||||
5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAnimation.xcodeproj; path = "../node_modules/react-native/Libraries/NativeAnimation/RCTAnimation.xcodeproj"; sourceTree = "<group>"; };
|
||||
634A8F047C73D24A87850EC0 /* Pods-Mattermost.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mattermost.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Mattermost/Pods-Mattermost.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
6561AEAC21CC40B8A72ABB93 /* OpenSans-Light.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "OpenSans-Light.ttf"; path = "../assets/fonts/OpenSans-Light.ttf"; sourceTree = "<group>"; };
|
||||
65FD5EA57EBAE06106094B2F /* libPods-Mattermost.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Mattermost.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
77810F0A063349439B0D8B6B /* libJailMonkey.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libJailMonkey.a; sourceTree = "<group>"; };
|
||||
78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = "<group>"; };
|
||||
79CB6EBA24FE4ABFB0C155F0 /* YTPlayerView-iframe-player.html */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "YTPlayerView-iframe-player.html"; path = "../node_modules/react-native-youtube/assets/YTPlayerView-iframe-player.html"; sourceTree = "<group>"; };
|
||||
7DCC3D826CE640AF8F491692 /* BVLinearGradient.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = BVLinearGradient.xcodeproj; path = "../node_modules/react-native-linear-gradient/BVLinearGradient.xcodeproj"; sourceTree = "<group>"; };
|
||||
7F26919B1EE1DC51007574FE /* RNNotifications.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RNNotifications.xcodeproj; path = "../node_modules/react-native-notifications/RNNotifications/RNNotifications.xcodeproj"; sourceTree = "<group>"; };
|
||||
7F292A701E8AB73400A450A3 /* SplashScreenResource */ = {isa = PBXFileReference; lastKnownFileType = folder; path = SplashScreenResource; sourceTree = "<group>"; };
|
||||
|
|
@ -489,12 +506,15 @@
|
|||
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = "<group>"; };
|
||||
85E82BCA0FD245EEA520D106 /* RNImagePicker.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNImagePicker.xcodeproj; path = "../node_modules/react-native-image-picker/ios/RNImagePicker.xcodeproj"; sourceTree = "<group>"; };
|
||||
8606EB1EB7E349EF8248933E /* libz.tbd */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
|
||||
8EAB7CA059E14A73918789B6 /* libRCTYouTube.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRCTYouTube.a; sourceTree = "<group>"; };
|
||||
9552041247E749308CE7B412 /* RNSentry.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNSentry.xcodeproj; path = "../node_modules/react-native-sentry/ios/RNSentry.xcodeproj"; sourceTree = "<group>"; };
|
||||
A2968536BEC74A4ABBB73BD9 /* RCTYouTube.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RCTYouTube.xcodeproj; path = "../node_modules/react-native-youtube/RCTYouTube.xcodeproj"; sourceTree = "<group>"; };
|
||||
AC6EB561E1F64C17A69D2FAD /* Entypo.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Entypo.ttf; path = "../node_modules/react-native-vector-icons/Fonts/Entypo.ttf"; sourceTree = "<group>"; };
|
||||
ACC6B9FDC0AD45A6BFA4FBCD /* libBVLinearGradient.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libBVLinearGradient.a; sourceTree = "<group>"; };
|
||||
B97AA6F961BB47D3A3297E8E /* RNDeviceInfo.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNDeviceInfo.xcodeproj; path = "../node_modules/react-native-device-info/RNDeviceInfo.xcodeproj"; sourceTree = "<group>"; };
|
||||
BC977883E2624E05975CA65B /* OpenSans-Regular.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "OpenSans-Regular.ttf"; path = "../assets/fonts/OpenSans-Regular.ttf"; sourceTree = "<group>"; };
|
||||
BE17F630DB5D41FD93F32D22 /* OpenSans-LightItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "OpenSans-LightItalic.ttf"; path = "../assets/fonts/OpenSans-LightItalic.ttf"; sourceTree = "<group>"; };
|
||||
BFB7025EA936C1B5DC9725C2 /* Pods-Mattermost.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mattermost.release.xcconfig"; path = "Pods/Target Support Files/Pods-Mattermost/Pods-Mattermost.release.xcconfig"; sourceTree = "<group>"; };
|
||||
C78A387124874496AD2C1466 /* OpenSans-Semibold.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "OpenSans-Semibold.ttf"; path = "../assets/fonts/OpenSans-Semibold.ttf"; sourceTree = "<group>"; };
|
||||
D0281D64B98143668D6AD42B /* RNLocalAuth.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNLocalAuth.xcodeproj; path = "../node_modules/react-native-local-auth/RNLocalAuth.xcodeproj"; sourceTree = "<group>"; };
|
||||
D4B1B363C2414DA19C1AC521 /* OpenSans-Bold.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "OpenSans-Bold.ttf"; path = "../assets/fonts/OpenSans-Bold.ttf"; sourceTree = "<group>"; };
|
||||
|
|
@ -513,6 +533,7 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
140ED2AC1D01E1AD002B40FF /* libReact.a in Frameworks */,
|
||||
F23C99AA5FA10E457A76803A /* libPods-MattermostTests.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
@ -551,6 +572,8 @@
|
|||
1B5204C4347D45A9A7AC3EA5 /* libReactNativeExceptionHandler.a in Frameworks */,
|
||||
CB1B312483534997BEE7E65E /* libRNSentry.a in Frameworks */,
|
||||
DEBCF44F1F46413BB407D316 /* libz.tbd in Frameworks */,
|
||||
5F190C97C28E4E5E93D933C0 /* libRCTYouTube.a in Frameworks */,
|
||||
A14B2A56A554E84DFE3D6580 /* libPods-Mattermost.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
@ -639,6 +662,7 @@
|
|||
BC977883E2624E05975CA65B /* OpenSans-Regular.ttf */,
|
||||
C78A387124874496AD2C1466 /* OpenSans-Semibold.ttf */,
|
||||
0E617BF0F36D4E738F51D169 /* OpenSans-SemiboldItalic.ttf */,
|
||||
79CB6EBA24FE4ABFB0C155F0 /* YTPlayerView-iframe-player.html */,
|
||||
);
|
||||
name = Resources;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -753,6 +777,26 @@
|
|||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
4B992D7BAAEDF8759DB525B5 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
65FD5EA57EBAE06106094B2F /* libPods-Mattermost.a */,
|
||||
4246DC09024BB33A3E491E25 /* libPods-MattermostTests.a */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
57D053CEA78013E949257E00 /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
634A8F047C73D24A87850EC0 /* Pods-Mattermost.debug.xcconfig */,
|
||||
BFB7025EA936C1B5DC9725C2 /* Pods-Mattermost.release.xcconfig */,
|
||||
3820CC3BBC4B0129958555A9 /* Pods-MattermostTests.debug.xcconfig */,
|
||||
41465DE822E9429EB8B90CB4 /* Pods-MattermostTests.release.xcconfig */,
|
||||
);
|
||||
name = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
5E91572E1DD0AC6500FF2AA8 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
|
@ -837,6 +881,30 @@
|
|||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7FA794CE1F61A1A400C02924 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7FA794ED1F61A1A500C02924 /* libRCTYouTube.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7FA795021F61A1A500C02924 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7FA795061F61A1A500C02924 /* libRNSentry.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7FA795071F61A1A500C02924 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7FA7950B1F61A1A500C02924 /* libReactNativeExceptionHandler.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7FC200BD1EBB65100099331B /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
|
@ -861,22 +929,6 @@
|
|||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7FEB105F1F6101090039A015 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7FEB10861F6101090039A015 /* libReactNativeExceptionHandler.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7FEB10611F6101090039A015 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7FEB10911F61010A0039A015 /* libRNSentry.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
832341AE1AAA6A7D00B99B32 /* Libraries */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
|
@ -911,6 +963,7 @@
|
|||
546CB0A5BB8F453890CBA559 /* RNFetchBlob.xcodeproj */,
|
||||
3B1E210BF3B649BBBF427977 /* ReactNativeExceptionHandler.xcodeproj */,
|
||||
9552041247E749308CE7B412 /* RNSentry.xcodeproj */,
|
||||
A2968536BEC74A4ABBB73BD9 /* RCTYouTube.xcodeproj */,
|
||||
);
|
||||
name = Libraries;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -933,6 +986,8 @@
|
|||
00E356EF1AD99517003FC87E /* MattermostTests */,
|
||||
83CBBA001A601CBA00E9B192 /* Products */,
|
||||
0156F464626F49C2977D7982 /* Resources */,
|
||||
57D053CEA78013E949257E00 /* Pods */,
|
||||
4B992D7BAAEDF8759DB525B5 /* Frameworks */,
|
||||
);
|
||||
indentWidth = 2;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -954,9 +1009,12 @@
|
|||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "MattermostTests" */;
|
||||
buildPhases = (
|
||||
EEC0B569A776EB6F23DA5874 /* [CP] Check Pods Manifest.lock */,
|
||||
00E356EA1AD99517003FC87E /* Sources */,
|
||||
00E356EB1AD99517003FC87E /* Frameworks */,
|
||||
00E356EC1AD99517003FC87E /* Resources */,
|
||||
24BAEFA847BB924860ACEAE9 /* [CP] Embed Pods Frameworks */,
|
||||
1E7A58BF4E81655D1CC6DCC6 /* [CP] Copy Pods Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
|
|
@ -972,12 +1030,15 @@
|
|||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "Mattermost" */;
|
||||
buildPhases = (
|
||||
0D421A536CD412E685542AA3 /* [CP] Check Pods Manifest.lock */,
|
||||
13B07F871A680F5B00A75B9A /* Sources */,
|
||||
13B07F8C1A680F5B00A75B9A /* Frameworks */,
|
||||
13B07F8E1A680F5B00A75B9A /* Resources */,
|
||||
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
|
||||
37DA4BA41E6F55AD002B058E /* Embed Frameworks */,
|
||||
AE4769B235D14E6C9C64EA78 /* Upload Debug Symbols to Sentry */,
|
||||
BC5024E82B42A23CE05E72ED /* [CP] Embed Pods Frameworks */,
|
||||
509B02AF14835503C5C6029D /* [CP] Copy Pods Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
|
|
@ -1092,12 +1153,16 @@
|
|||
ProductGroup = 139FDEE71B06529A00C62182 /* Products */;
|
||||
ProjectRef = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 7FA794CE1F61A1A400C02924 /* Products */;
|
||||
ProjectRef = A2968536BEC74A4ABBB73BD9 /* RCTYouTube.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 146834001AC3E56700842450 /* Products */;
|
||||
ProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 7FEB105F1F6101090039A015 /* Products */;
|
||||
ProductGroup = 7FA795071F61A1A500C02924 /* Products */;
|
||||
ProjectRef = 3B1E210BF3B649BBBF427977 /* ReactNativeExceptionHandler.xcodeproj */;
|
||||
},
|
||||
{
|
||||
|
|
@ -1133,7 +1198,7 @@
|
|||
ProjectRef = EBA6063A99C141098D40C67A /* RNPasscodeStatus.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 7FEB10611F6101090039A015 /* Products */;
|
||||
ProductGroup = 7FA795021F61A1A500C02924 /* Products */;
|
||||
ProjectRef = 9552041247E749308CE7B412 /* RNSentry.xcodeproj */;
|
||||
},
|
||||
{
|
||||
|
|
@ -1445,6 +1510,27 @@
|
|||
remoteRef = 7F906D961E6A1ADF00B8F49A /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
7FA794ED1F61A1A500C02924 /* libRCTYouTube.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTYouTube.a;
|
||||
remoteRef = 7FA794EC1F61A1A500C02924 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
7FA795061F61A1A500C02924 /* libRNSentry.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRNSentry.a;
|
||||
remoteRef = 7FA795051F61A1A500C02924 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
7FA7950B1F61A1A500C02924 /* libReactNativeExceptionHandler.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libReactNativeExceptionHandler.a;
|
||||
remoteRef = 7FA7950A1F61A1A500C02924 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
7FC200DF1EBB65100099331B /* libReactNativeNavigation.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
|
|
@ -1466,20 +1552,6 @@
|
|||
remoteRef = 7FDF290B1E1F4B4E00DBBE56 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
7FEB10861F6101090039A015 /* libReactNativeExceptionHandler.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libReactNativeExceptionHandler.a;
|
||||
remoteRef = 7FEB10851F6101090039A015 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
7FEB10911F61010A0039A015 /* libRNSentry.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRNSentry.a;
|
||||
remoteRef = 7FEB10901F61010A0039A015 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
832341B51AAA6A8300B99B32 /* libRCTText.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
|
|
@ -1525,6 +1597,7 @@
|
|||
A08D512E7ADC40CCAD055A9E /* OpenSans-Regular.ttf in Resources */,
|
||||
62A8448264674B4D95A5A7C2 /* OpenSans-Semibold.ttf in Resources */,
|
||||
69AC753E496743BABB7A7124 /* OpenSans-SemiboldItalic.ttf in Resources */,
|
||||
5CB86E9DFB94485CAA748DF3 /* YTPlayerView-iframe-player.html in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
@ -1545,6 +1618,69 @@
|
|||
shellPath = /bin/sh;
|
||||
shellScript = ./bundleReactNative.sh;
|
||||
};
|
||||
0D421A536CD412E685542AA3 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-Mattermost-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
1E7A58BF4E81655D1CC6DCC6 /* [CP] Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-MattermostTests/Pods-MattermostTests-resources.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
24BAEFA847BB924860ACEAE9 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-MattermostTests/Pods-MattermostTests-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
509B02AF14835503C5C6029D /* [CP] Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Mattermost/Pods-Mattermost-resources.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
AE4769B235D14E6C9C64EA78 /* Upload Debug Symbols to Sentry */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
|
@ -1559,6 +1695,39 @@
|
|||
shellPath = /bin/sh;
|
||||
shellScript = ./uploadDebugSymbols.sh;
|
||||
};
|
||||
BC5024E82B42A23CE05E72ED /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Mattermost/Pods-Mattermost-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
EEC0B569A776EB6F23DA5874 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-MattermostTests-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
|
|
@ -1595,16 +1764,26 @@
|
|||
/* Begin XCBuildConfiguration section */
|
||||
00E356F61AD99517003FC87E /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 3820CC3BBC4B0129958555A9 /* Pods-MattermostTests.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
HEADER_SEARCH_PATHS = "$(inherited)";
|
||||
INFOPLIST_FILE = MattermostTests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
);
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
"-lc++",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Mattermost.app/Mattermost";
|
||||
|
|
@ -1613,13 +1792,23 @@
|
|||
};
|
||||
00E356F71AD99517003FC87E /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 41465DE822E9429EB8B90CB4 /* Pods-MattermostTests.release.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
HEADER_SEARCH_PATHS = "$(inherited)";
|
||||
INFOPLIST_FILE = MattermostTests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
);
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
"-lc++",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Mattermost.app/Mattermost";
|
||||
|
|
@ -1628,6 +1817,7 @@
|
|||
};
|
||||
13B07F941A680F5B00A75B9A /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 634A8F047C73D24A87850EC0 /* Pods-Mattermost.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
|
|
@ -1652,6 +1842,7 @@
|
|||
"$(SRCROOT)/../node_modules/react-native-fetch-blob/ios/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-exception-handler/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-sentry/ios/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-youtube/**",
|
||||
);
|
||||
INFOPLIST_FILE = Mattermost/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
|
|
@ -1670,6 +1861,7 @@
|
|||
};
|
||||
13B07F951A680F5B00A75B9A /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = BFB7025EA936C1B5DC9725C2 /* Pods-Mattermost.release.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
|
|
@ -1694,6 +1886,7 @@
|
|||
"$(SRCROOT)/../node_modules/react-native-fetch-blob/ios/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-exception-handler/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-sentry/ios/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-youtube/**",
|
||||
);
|
||||
INFOPLIST_FILE = Mattermost/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
|
|
|
|||
10
ios/Mattermost.xcworkspace/contents.xcworkspacedata
generated
Normal file
10
ios/Mattermost.xcworkspace/contents.xcworkspacedata
generated
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Mattermost.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Pods/Pods.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
*/
|
||||
|
||||
#import "AppDelegate.h"
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#import <React/RCTBundleURLProvider.h>
|
||||
#import <React/RCTRootView.h>
|
||||
#if __has_include(<React/RNSentry.h>)
|
||||
|
|
@ -31,6 +32,7 @@
|
|||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
self.window.backgroundColor = [UIColor whiteColor];
|
||||
[[RCCManager sharedInstance] initBridgeWithBundleURL:jsCodeLocation launchOptions:launchOptions];
|
||||
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error: nil];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,99 +1,99 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Mattermost Beta</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.2.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>49</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
<key>NSExceptionDomains</key>
|
||||
<dict>
|
||||
<key>localhost</key>
|
||||
<dict>
|
||||
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>Take a Photo or Video and upload it to your mattermost instance</string>
|
||||
<key>NSLocationWhenInUseUsageDescription</key>
|
||||
<string/>
|
||||
<key>NSPhotoLibraryUsageDescription</key>
|
||||
<string>Upload Photos and Videos to your Mattermost instance</string>
|
||||
<key>UIAppFonts</key>
|
||||
<array>
|
||||
<string>Entypo.ttf</string>
|
||||
<string>EvilIcons.ttf</string>
|
||||
<string>FontAwesome.ttf</string>
|
||||
<string>Foundation.ttf</string>
|
||||
<string>Ionicons.ttf</string>
|
||||
<string>MaterialIcons.ttf</string>
|
||||
<string>Octicons.ttf</string>
|
||||
<string>Zocial.ttf</string>
|
||||
<string>MaterialCommunityIcons.ttf</string>
|
||||
<string>SimpleLineIcons.ttf</string>
|
||||
<string>OpenSans-Bold.ttf</string>
|
||||
<string>OpenSans-BoldItalic.ttf</string>
|
||||
<string>OpenSans-ExtraBold.ttf</string>
|
||||
<string>OpenSans-ExtraBoldItalic.ttf</string>
|
||||
<string>OpenSans-Italic.ttf</string>
|
||||
<string>OpenSans-Light.ttf</string>
|
||||
<string>OpenSans-LightItalic.ttf</string>
|
||||
<string>OpenSans-Regular.ttf</string>
|
||||
<string>OpenSans-Semibold.ttf</string>
|
||||
<string>OpenSans-SemiboldItalic.ttf</string>
|
||||
</array>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
<key>CFBundleURLTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleURLName</key>
|
||||
<string>com.mattermost.rnbeta</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>mattermost</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Mattermost Beta</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.2.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>49</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
<key>NSExceptionDomains</key>
|
||||
<dict>
|
||||
<key>localhost</key>
|
||||
<dict>
|
||||
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>Take a Photo or Video and upload it to your mattermost instance</string>
|
||||
<key>NSLocationWhenInUseUsageDescription</key>
|
||||
<string/>
|
||||
<key>NSPhotoLibraryUsageDescription</key>
|
||||
<string>Upload Photos and Videos to your Mattermost instance</string>
|
||||
<key>UIAppFonts</key>
|
||||
<array>
|
||||
<string>Entypo.ttf</string>
|
||||
<string>EvilIcons.ttf</string>
|
||||
<string>FontAwesome.ttf</string>
|
||||
<string>Foundation.ttf</string>
|
||||
<string>Ionicons.ttf</string>
|
||||
<string>MaterialIcons.ttf</string>
|
||||
<string>Octicons.ttf</string>
|
||||
<string>Zocial.ttf</string>
|
||||
<string>MaterialCommunityIcons.ttf</string>
|
||||
<string>SimpleLineIcons.ttf</string>
|
||||
<string>OpenSans-Bold.ttf</string>
|
||||
<string>OpenSans-BoldItalic.ttf</string>
|
||||
<string>OpenSans-ExtraBold.ttf</string>
|
||||
<string>OpenSans-ExtraBoldItalic.ttf</string>
|
||||
<string>OpenSans-Italic.ttf</string>
|
||||
<string>OpenSans-Light.ttf</string>
|
||||
<string>OpenSans-LightItalic.ttf</string>
|
||||
<string>OpenSans-Regular.ttf</string>
|
||||
<string>OpenSans-Semibold.ttf</string>
|
||||
<string>OpenSans-SemiboldItalic.ttf</string>
|
||||
</array>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
<key>CFBundleURLTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleURLName</key>
|
||||
<string>com.mattermost.rnbeta</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>mattermost</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
16
ios/Podfile
Normal file
16
ios/Podfile
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
# Uncomment the next line to define a global platform for your project
|
||||
# platform :ios, '9.0'
|
||||
|
||||
target 'Mattermost' do
|
||||
# Uncomment the next line if you're using Swift or would like to use dynamic frameworks
|
||||
# use_frameworks!
|
||||
|
||||
# Pods for Mattermost
|
||||
pod 'XCDYouTubeKit', '2.5'
|
||||
|
||||
target 'MattermostTests' do
|
||||
inherit! :search_paths
|
||||
# Pods for testing
|
||||
end
|
||||
|
||||
end
|
||||
12
ios/Podfile.lock
Normal file
12
ios/Podfile.lock
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
PODS:
|
||||
- XCDYouTubeKit (2.5.0)
|
||||
|
||||
DEPENDENCIES:
|
||||
- XCDYouTubeKit (= 2.5)
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
XCDYouTubeKit: 9db45d0f5af8fb5a47561ac7f2fe6de885f57453
|
||||
|
||||
PODFILE CHECKSUM: 76eab0e20eee91ac7f71b70b29082dce0d6eba08
|
||||
|
||||
COCOAPODS: 1.3.0
|
||||
|
|
@ -43,6 +43,7 @@
|
|||
"react-native-swiper": "1.5.4",
|
||||
"react-native-tooltip": "enahum/react-native-tooltip",
|
||||
"react-native-vector-icons": "4.1.1",
|
||||
"react-native-youtube": "1.0.0-beta.3",
|
||||
"react-redux": "5.0.4",
|
||||
"redux": "3.6.0",
|
||||
"redux-batched-actions": "0.2.0",
|
||||
|
|
@ -52,7 +53,8 @@
|
|||
"reselect": "3.0.1",
|
||||
"semver": "5.3.0",
|
||||
"tinycolor2": "1.4.1",
|
||||
"url-parse": "1.1.9"
|
||||
"url-parse": "1.1.9",
|
||||
"youtube-video-id": "0.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-cli": "6.24.1",
|
||||
|
|
|
|||
24
yarn.lock
24
yarn.lock
|
|
@ -4363,7 +4363,7 @@ promise@^7.1.1:
|
|||
dependencies:
|
||||
asap "~2.0.3"
|
||||
|
||||
prop-types@15.5.10, prop-types@^15.0.0, prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.8, prop-types@~15.5.7:
|
||||
prop-types@15.5.10, prop-types@^15.0.0, prop-types@^15.5.0, prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.8, prop-types@~15.5.7:
|
||||
version "15.5.10"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.10.tgz#2797dfc3126182e3a95e3dfbb2e893ddd7456154"
|
||||
dependencies:
|
||||
|
|
@ -4580,6 +4580,12 @@ react-native-exception-handler@2.0.1:
|
|||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/react-native-exception-handler/-/react-native-exception-handler-2.0.1.tgz#4ab9fc668927c2672adfffce3784316d81f130e8"
|
||||
|
||||
react-native-fast-image@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/react-native-fast-image/-/react-native-fast-image-1.0.0.tgz#a88337efa18fd34d530bab9ee05680374f3e2a2d"
|
||||
dependencies:
|
||||
prop-types "^15.5.10"
|
||||
|
||||
react-native-fetch-blob@0.10.8:
|
||||
version "0.10.8"
|
||||
resolved "https://registry.yarnpkg.com/react-native-fetch-blob/-/react-native-fetch-blob-0.10.8.tgz#4fc256abae0cb5f10e7c41f28c11b3ff330d72a9"
|
||||
|
|
@ -4587,12 +4593,6 @@ react-native-fetch-blob@0.10.8:
|
|||
base-64 "0.1.0"
|
||||
glob "7.0.6"
|
||||
|
||||
react-native-fast-image@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/react-native-fast-image/-/react-native-fast-image-1.0.0.tgz#a88337efa18fd34d530bab9ee05680374f3e2a2d"
|
||||
dependencies:
|
||||
prop-types "^15.5.10"
|
||||
|
||||
react-native-image-picker@jp928/react-native-image-picker#6ee35b69f3dbd6c7c66f580fd4d9eabf398703d4:
|
||||
version "0.26.2"
|
||||
resolved "https://codeload.github.com/jp928/react-native-image-picker/tar.gz/6ee35b69f3dbd6c7c66f580fd4d9eabf398703d4"
|
||||
|
|
@ -4708,6 +4708,12 @@ react-native-vector-icons@4.1.1:
|
|||
prop-types "^15.5.8"
|
||||
yargs "^6.3.0"
|
||||
|
||||
react-native-youtube@1.0.0-beta.3:
|
||||
version "1.0.0-beta.3"
|
||||
resolved "https://registry.yarnpkg.com/react-native-youtube/-/react-native-youtube-1.0.0-beta.3.tgz#0dc51c943cd92868c1457880d78dd5ba72b6001a"
|
||||
dependencies:
|
||||
prop-types "^15.5.0"
|
||||
|
||||
react-native@0.44.0:
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.44.0.tgz#06427a30053f2d555c60fe0b9afcc6c778db09de"
|
||||
|
|
@ -6256,3 +6262,7 @@ yargs@~3.10.0:
|
|||
cliui "^2.1.0"
|
||||
decamelize "^1.0.0"
|
||||
window-size "0.1.0"
|
||||
|
||||
youtube-video-id@0.0.2:
|
||||
version "0.0.2"
|
||||
resolved "https://registry.yarnpkg.com/youtube-video-id/-/youtube-video-id-0.0.2.tgz#1c2874b8c6d36ef140c36739336863e22f49e438"
|
||||
|
|
|
|||
Loading…
Reference in a new issue