Upgrade to RN 0.48.3 (#911)

* Upgrade to RN 0.48.1

* Update deps to be exact

* Fix tests

* Remove unneeded code from setup and add socketcluster dep

* Fix drawer pan issue

* Fix bridge issues on iOS

* Upgrade to RN 0.48.3

* Search to use RN SectionList
This commit is contained in:
enahum 2017-09-18 13:01:47 -03:00 committed by Harrison Healey
parent acc7fedd0e
commit 0628cbc693
43 changed files with 2781 additions and 1652 deletions

708
ImagePickerModule.java Normal file
View file

@ -0,0 +1,708 @@
package com.imagepicker;
import android.Manifest;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.provider.MediaStore;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.StyleRes;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Patterns;
import android.webkit.MimeTypeMap;
import android.content.pm.PackageManager;
import com.facebook.react.ReactActivity;
import com.facebook.react.bridge.ActivityEventListener;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.imagepicker.media.ImageConfig;
import com.imagepicker.permissions.PermissionUtils;
import com.imagepicker.permissions.OnImagePickerPermissionsCallback;
import com.imagepicker.utils.MediaUtils.ReadExifResult;
import com.imagepicker.utils.RealPathUtil;
import com.imagepicker.utils.UI;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ref.WeakReference;
import com.facebook.react.modules.core.PermissionListener;
import com.facebook.react.modules.core.PermissionAwareActivity;
import static com.imagepicker.utils.MediaUtils.*;
import static com.imagepicker.utils.MediaUtils.createNewFile;
import static com.imagepicker.utils.MediaUtils.getResizedImage;
public class ImagePickerModule extends ReactContextBaseJavaModule
implements ActivityEventListener
{
public static final int REQUEST_LAUNCH_IMAGE_CAPTURE = 13001;
public static final int REQUEST_LAUNCH_IMAGE_LIBRARY = 13002;
public static final int REQUEST_LAUNCH_VIDEO_LIBRARY = 13003;
public static final int REQUEST_LAUNCH_VIDEO_CAPTURE = 13004;
public static final int REQUEST_PERMISSIONS_FOR_CAMERA = 14001;
public static final int REQUEST_PERMISSIONS_FOR_LIBRARY = 14002;
private final ReactApplicationContext reactContext;
private final int dialogThemeId;
protected Callback callback;
private ReadableMap options;
protected Uri cameraCaptureURI;
private Boolean noData = false;
private Boolean pickVideo = false;
private ImageConfig imageConfig = new ImageConfig(null, null, 0, 0, 100, 0, false);
@Deprecated
private int videoQuality = 1;
@Deprecated
private int videoDurationLimit = 0;
private ResponseHelper responseHelper = new ResponseHelper();
private PermissionListener listener = new PermissionListener()
{
public boolean onRequestPermissionsResult(final int requestCode,
@NonNull final String[] permissions,
@NonNull final int[] grantResults)
{
boolean permissionsGranted = true;
for (int i = 0; i < permissions.length; i++)
{
final boolean granted = grantResults[i] == PackageManager.PERMISSION_GRANTED;
permissionsGranted = permissionsGranted && granted;
}
if (callback == null || options == null)
{
return false;
}
if (!permissionsGranted)
{
responseHelper.invokeError(callback, "Permissions weren't granted");
return false;
}
switch (requestCode)
{
case REQUEST_PERMISSIONS_FOR_CAMERA:
launchCamera(options, callback);
break;
case REQUEST_PERMISSIONS_FOR_LIBRARY:
launchImageLibrary(options, callback);
break;
}
return true;
}
};
public ImagePickerModule(ReactApplicationContext reactContext,
@StyleRes final int dialogThemeId)
{
super(reactContext);
this.dialogThemeId = dialogThemeId;
this.reactContext = reactContext;
this.reactContext.addActivityEventListener(this);
}
@Override
public String getName() {
return "ImagePickerManager";
}
@ReactMethod
public void showImagePicker(final ReadableMap options, final Callback callback) {
Activity currentActivity = getCurrentActivity();
if (currentActivity == null)
{
responseHelper.invokeError(callback, "can't find current Activity");
return;
}
this.callback = callback;
this.options = options;
imageConfig = new ImageConfig(null, null, 0, 0, 100, 0, false);
final AlertDialog dialog = UI.chooseDialog(this, options, new UI.OnAction()
{
@Override
public void onTakePhoto(@NonNull final ImagePickerModule module)
{
if (module == null)
{
return;
}
module.launchCamera();
}
@Override
public void onUseLibrary(@NonNull final ImagePickerModule module)
{
if (module == null)
{
return;
}
module.launchImageLibrary();
}
@Override
public void onCancel(@NonNull final ImagePickerModule module)
{
if (module == null)
{
return;
}
module.doOnCancel();
}
@Override
public void onCustomButton(@NonNull final ImagePickerModule module,
@NonNull final String action)
{
if (module == null)
{
return;
}
module.invokeCustomButton(action);
}
});
dialog.show();
}
public void doOnCancel()
{
responseHelper.invokeCancel(callback);
}
public void launchCamera()
{
this.launchCamera(this.options, this.callback);
}
// NOTE: Currently not reentrant / doesn't support concurrent requests
@ReactMethod
public void launchCamera(final ReadableMap options, final Callback callback)
{
if (!isCameraAvailable())
{
responseHelper.invokeError(callback, "Camera not available");
return;
}
final Activity currentActivity = getCurrentActivity();
if (currentActivity == null)
{
responseHelper.invokeError(callback, "can't find current Activity");
return;
}
this.options = options;
if (!permissionsCheck(currentActivity, callback, REQUEST_PERMISSIONS_FOR_CAMERA))
{
return;
}
parseOptions(this.options);
int requestCode;
Intent cameraIntent;
if (pickVideo)
{
requestCode = REQUEST_LAUNCH_VIDEO_CAPTURE;
cameraIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, videoQuality);
if (videoDurationLimit > 0)
{
cameraIntent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, videoDurationLimit);
}
}
else
{
requestCode = REQUEST_LAUNCH_IMAGE_CAPTURE;
cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
final File original = createNewFile(reactContext, this.options, false);
imageConfig = imageConfig.withOriginalFile(original);
cameraCaptureURI = RealPathUtil.compatUriFromFile(reactContext, imageConfig.original);
if (cameraCaptureURI == null)
{
responseHelper.invokeError(callback, "Couldn't get file path for photo");
return;
}
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, cameraCaptureURI);
}
if (cameraIntent.resolveActivity(reactContext.getPackageManager()) == null)
{
responseHelper.invokeError(callback, "Cannot launch camera");
return;
}
this.callback = callback;
try
{
currentActivity.startActivityForResult(cameraIntent, requestCode);
}
catch (ActivityNotFoundException e)
{
e.printStackTrace();
responseHelper.invokeError(callback, "Cannot launch camera");
}
}
public void launchImageLibrary()
{
this.launchImageLibrary(this.options, this.callback);
}
// NOTE: Currently not reentrant / doesn't support concurrent requests
@ReactMethod
public void launchImageLibrary(final ReadableMap options, final Callback callback)
{
final Activity currentActivity = getCurrentActivity();
if (currentActivity == null) {
responseHelper.invokeError(callback, "can't find current Activity");
return;
}
this.options = options;
if (!permissionsCheck(currentActivity, callback, REQUEST_PERMISSIONS_FOR_LIBRARY))
{
return;
}
parseOptions(this.options);
int requestCode;
Intent libraryIntent;
if (pickVideo)
{
requestCode = REQUEST_LAUNCH_VIDEO_LIBRARY;
libraryIntent = new Intent(Intent.ACTION_PICK);
libraryIntent.setType("video/*");
}
else
{
requestCode = REQUEST_LAUNCH_IMAGE_LIBRARY;
libraryIntent = new Intent(Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
}
if (libraryIntent.resolveActivity(reactContext.getPackageManager()) == null)
{
responseHelper.invokeError(callback, "Cannot launch photo library");
return;
}
this.callback = callback;
try
{
currentActivity.startActivityForResult(libraryIntent, requestCode);
}
catch (ActivityNotFoundException e)
{
e.printStackTrace();
responseHelper.invokeError(callback, "Cannot launch photo library");
}
}
@Override
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
//robustness code
if (passResult(requestCode))
{
return;
}
responseHelper.cleanResponse();
// user cancel
if (resultCode != Activity.RESULT_OK)
{
removeUselessFiles(requestCode, imageConfig);
responseHelper.invokeCancel(callback);
callback = null;
return;
}
Uri uri = null;
switch (requestCode)
{
case REQUEST_LAUNCH_IMAGE_CAPTURE:
uri = cameraCaptureURI;
break;
case REQUEST_LAUNCH_IMAGE_LIBRARY:
uri = data.getData();
String realPath = getRealPathFromURI(uri);
final boolean isUrl = !TextUtils.isEmpty(realPath) &&
Patterns.WEB_URL.matcher(realPath).matches();
if (realPath == null || isUrl)
{
try
{
File file = createFileFromURI(uri);
realPath = file.getAbsolutePath();
uri = Uri.fromFile(file);
}
catch (Exception e)
{
// image not in cache
responseHelper.putString("error", "Could not read photo");
responseHelper.putString("uri", uri.toString());
responseHelper.invokeResponse(callback);
callback = null;
return;
}
}
imageConfig = imageConfig.withOriginalFile(new File(realPath));
break;
case REQUEST_LAUNCH_VIDEO_LIBRARY:
responseHelper.putString("uri", data.getData().toString());
responseHelper.putString("path", getRealPathFromURI(data.getData()));
responseHelper.invokeResponse(callback);
callback = null;
return;
case REQUEST_LAUNCH_VIDEO_CAPTURE:
final String path = getRealPathFromURI(data.getData());
responseHelper.putString("uri", data.getData().toString());
responseHelper.putString("path", path);
fileScan(reactContext, path);
responseHelper.invokeResponse(callback);
callback = null;
return;
}
final ReadExifResult result = readExifInterface(responseHelper, imageConfig);
if (result.error != null)
{
removeUselessFiles(requestCode, imageConfig);
responseHelper.invokeError(callback, result.error.getMessage());
callback = null;
return;
}
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(imageConfig.original.getAbsolutePath(), options);
int initialWidth = options.outWidth;
int initialHeight = options.outHeight;
updatedResultResponse(uri, imageConfig.original.getAbsolutePath());
// don't create a new file if contraint are respected
if (imageConfig.useOriginal(initialWidth, initialHeight, result.currentRotation))
{
responseHelper.putInt("width", initialWidth);
responseHelper.putInt("height", initialHeight);
fileScan(reactContext, imageConfig.original.getAbsolutePath());
}
else
{
imageConfig = getResizedImage(reactContext, this.options, imageConfig, initialWidth, initialHeight, requestCode);
if (imageConfig.resized == null)
{
removeUselessFiles(requestCode, imageConfig);
responseHelper.putString("error", "Can't resize the image");
}
else
{
uri = Uri.fromFile(imageConfig.resized);
BitmapFactory.decodeFile(imageConfig.resized.getAbsolutePath(), options);
responseHelper.putInt("width", options.outWidth);
responseHelper.putInt("height", options.outHeight);
updatedResultResponse(uri, imageConfig.resized.getAbsolutePath());
fileScan(reactContext, imageConfig.resized.getAbsolutePath());
}
}
if (imageConfig.saveToCameraRoll && requestCode == REQUEST_LAUNCH_IMAGE_CAPTURE)
{
final RolloutPhotoResult rolloutResult = rolloutPhotoFromCamera(imageConfig);
if (rolloutResult.error == null)
{
imageConfig = rolloutResult.imageConfig;
uri = Uri.fromFile(imageConfig.getActualFile());
updatedResultResponse(uri, imageConfig.getActualFile().getAbsolutePath());
}
else
{
removeUselessFiles(requestCode, imageConfig);
final String errorMessage = new StringBuilder("Error moving image to camera roll: ")
.append(rolloutResult.error.getMessage()).toString();
responseHelper.putString("error", errorMessage);
return;
}
}
responseHelper.invokeResponse(callback);
callback = null;
this.options = null;
}
public void invokeCustomButton(@NonNull final String action)
{
responseHelper.invokeCustomButton(this.callback, action);
}
@Override
public void onNewIntent(Intent intent) { }
public Context getContext()
{
return getReactApplicationContext();
}
public @StyleRes int getDialogThemeId()
{
return this.dialogThemeId;
}
public @NonNull Activity getActivity()
{
return getCurrentActivity();
}
private boolean passResult(int requestCode)
{
return callback == null || (cameraCaptureURI == null && requestCode == REQUEST_LAUNCH_IMAGE_CAPTURE)
|| (requestCode != REQUEST_LAUNCH_IMAGE_CAPTURE && requestCode != REQUEST_LAUNCH_IMAGE_LIBRARY
&& requestCode != REQUEST_LAUNCH_VIDEO_LIBRARY && requestCode != REQUEST_LAUNCH_VIDEO_CAPTURE);
}
private void updatedResultResponse(@Nullable final Uri uri,
@NonNull final String path)
{
responseHelper.putString("uri", uri.toString());
responseHelper.putString("path", path);
if (!noData) {
responseHelper.putString("data", getBase64StringFromFile(path));
}
putExtraFileInfo(path, responseHelper);
}
private boolean permissionsCheck(@NonNull final Activity activity,
@NonNull final Callback callback,
@NonNull final int requestCode)
{
final int writePermission = ActivityCompat
.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
final int cameraPermission = ActivityCompat
.checkSelfPermission(activity, Manifest.permission.CAMERA);
final boolean permissionsGrated = writePermission == PackageManager.PERMISSION_GRANTED &&
cameraPermission == PackageManager.PERMISSION_GRANTED;
if (!permissionsGrated)
{
final Boolean dontAskAgain = ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) && ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.CAMERA);
if (dontAskAgain)
{
final AlertDialog dialog = PermissionUtils
.explainingDialog(this, options, new PermissionUtils.OnExplainingPermissionCallback()
{
@Override
public void onCancel(WeakReference<ImagePickerModule> moduleInstance,
DialogInterface dialogInterface)
{
final ImagePickerModule module = moduleInstance.get();
if (module == null)
{
return;
}
module.doOnCancel();
}
@Override
public void onReTry(WeakReference<ImagePickerModule> moduleInstance,
DialogInterface dialogInterface)
{
final ImagePickerModule module = moduleInstance.get();
if (module == null)
{
return;
}
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", module.getContext().getPackageName(), null);
intent.setData(uri);
final Activity innerActivity = module.getActivity();
if (innerActivity == null)
{
return;
}
innerActivity.startActivityForResult(intent, 1);
}
});
dialog.show();
return false;
}
else
{
String[] PERMISSIONS = {Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA};
if (activity instanceof ReactActivity)
{
((ReactActivity) activity).requestPermissions(PERMISSIONS, requestCode, listener);
}
else if (activity instanceof OnImagePickerPermissionsCallback)
{
((OnImagePickerPermissionsCallback) activity).setPermissionListener(listener);
ActivityCompat.requestPermissions(activity, PERMISSIONS, requestCode);
}
else if (activity instanceof PermissionAwareActivity) {
((PermissionAwareActivity) activity).requestPermissions(PERMISSIONS, requestCode, listener);
}
else
{
final String errorDescription = new StringBuilder(activity.getClass().getSimpleName())
.append(" must implement ")
.append(OnImagePickerPermissionsCallback.class.getSimpleName())
.append(PermissionAwareActivity.class.getSimpleName())
.toString();
throw new UnsupportedOperationException(errorDescription);
}
return false;
}
}
return true;
}
private boolean isCameraAvailable() {
return reactContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)
|| reactContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY);
}
private @NonNull String getRealPathFromURI(@NonNull final Uri uri) {
return RealPathUtil.getRealPathFromURI(reactContext, uri);
}
/**
* Create a file from uri to allow image picking of image in disk cache
* (Exemple: facebook image, google image etc..)
*
* @doc =>
* https://github.com/nostra13/Android-Universal-Image-Loader#load--display-task-flow
*
* @param uri
* @return File
* @throws Exception
*/
private File createFileFromURI(Uri uri) throws Exception {
File file = new File(reactContext.getExternalCacheDir(), "photo-" + uri.getLastPathSegment());
InputStream input = reactContext.getContentResolver().openInputStream(uri);
OutputStream output = new FileOutputStream(file);
try {
byte[] buffer = new byte[4 * 1024];
int read;
while ((read = input.read(buffer)) != -1) {
output.write(buffer, 0, read);
}
output.flush();
} finally {
output.close();
input.close();
}
return file;
}
private String getBase64StringFromFile(String absoluteFilePath) {
InputStream inputStream = null;
try {
inputStream = new FileInputStream(new File(absoluteFilePath));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
byte[] bytes;
byte[] buffer = new byte[8192];
int bytesRead;
ByteArrayOutputStream output = new ByteArrayOutputStream();
try {
while ((bytesRead = inputStream.read(buffer)) != -1) {
output.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace();
}
bytes = output.toByteArray();
return Base64.encodeToString(bytes, Base64.NO_WRAP);
}
private void putExtraFileInfo(@NonNull final String path,
@NonNull final ResponseHelper responseHelper)
{
// size && filename
try {
File f = new File(path);
responseHelper.putDouble("fileSize", f.length());
responseHelper.putString("fileName", f.getName());
} catch (Exception e) {
e.printStackTrace();
}
// type
String extension = MimeTypeMap.getFileExtensionFromUrl(path);
if (extension != null) {
responseHelper.putString("type", MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension));
}
}
private void parseOptions(final ReadableMap options) {
noData = false;
if (options.hasKey("noData")) {
noData = options.getBoolean("noData");
}
imageConfig = imageConfig.updateFromOptions(options);
pickVideo = false;
if (options.hasKey("mediaType") && options.getString("mediaType").equals("video")) {
pickVideo = true;
}
videoQuality = 1;
if (options.hasKey("videoQuality") && options.getString("videoQuality").equals("low")) {
videoQuality = 0;
}
videoDurationLimit = 0;
if (options.hasKey("durationLimit")) {
videoDurationLimit = options.getInt("durationLimit");
}
}
}

View file

@ -107,7 +107,9 @@ clean:
post-install:
./node_modules/.bin/remotedev-debugger --hostname localhost --port 5678 --injectserver
@# Must remove the .babelrc for 0.42.0 to work correctly
rm -f node_modules/intl/.babelrc
@# Need to copy custom ImagePickerModule.java that implements correct permission checks for android
@rm node_modules/react-native-image-picker/android/src/main/java/com/imagepicker/ImagePickerModule.java
@cp ./ImagePickerModule.java node_modules/react-native-image-picker/android/src/main/java/com/imagepicker
@# Hack to get react-intl and its dependencies to work with react-native
@# Based off of https://github.com/este/este/blob/master/gulp/native-fix.js
sed -i'' -e 's|"./locale-data/index.js": false|"./locale-data/index.js": "./locale-data/index.js"|g' node_modules/react-intl/package.json

View file

@ -176,11 +176,11 @@ dependencies {
compile project(':react-native-fetch-blob')
// For animated GIF support
compile 'com.facebook.fresco:animated-base-support:1.0.1'
compile 'com.facebook.fresco:animated-base-support:1.3.0'
// 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'
compile 'com.facebook.fresco:animated-gif:1.3.0'
compile 'com.facebook.fresco:animated-webp:1.3.0'
compile 'com.facebook.fresco:webpsupport:1.3.0'
}
// Run this once to be able to run the application with BUCK

View file

@ -25,11 +25,6 @@ public class MattermostPackage implements ReactPackage {
);
}
@Override
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();

View file

@ -14,7 +14,7 @@ import Drawer from 'app/components/drawer';
import {alertErrorWithFallback} from 'app/utils/general';
import ChannelsList from './channels_list';
import Swiper from './swiper';
import DrawerSwiper from './drawer_swipper';
import TeamsList from './teams_list';
import {General} from 'mattermost-redux/constants';
@ -271,18 +271,15 @@ export default class ChannelDrawer extends PureComponent {
const {openDrawerOffset} = this.state;
const showTeams = openDrawerOffset === DRAWER_INITIAL_OFFSET && Object.keys(myTeamMembers).length > 1;
let teams;
if (showTeams) {
teams = (
<View style={{flex: 1, marginBottom: 10}}>
<TeamsList
closeChannelDrawer={this.closeChannelDrawer}
myTeamMembers={myTeamMembers}
navigator={navigator}
/>
</View>
);
}
const teams = (
<View style={{flex: 1, marginBottom: 10}}>
<TeamsList
closeChannelDrawer={this.closeChannelDrawer}
myTeamMembers={myTeamMembers}
navigator={navigator}
/>
</View>
);
const channelsList = (
<View style={{flex: 1, marginBottom: 10}}>
@ -304,7 +301,7 @@ export default class ChannelDrawer extends PureComponent {
);
return (
<Swiper
<DrawerSwiper
ref='swiper'
onPageSelected={this.onPageSelected}
openDrawerOffset={openDrawerOffset}
@ -313,7 +310,7 @@ export default class ChannelDrawer extends PureComponent {
>
{teams}
{channelsList}
</Swiper>
</DrawerSwiper>
);
};
@ -332,6 +329,7 @@ export default class ChannelDrawer extends PureComponent {
captureGestures='open'
type='static'
acceptTap={true}
acceptPanOnDrawer={true}
disabled={false}
content={this.renderContent()}
tapToClose={true}

View file

@ -250,11 +250,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
flex: 1
},
extraPadding: {
...Platform.select({
ios: {
paddingBottom: 10
}
})
paddingBottom: 5
},
statusBar: {
backgroundColor: theme.sidebarHeaderBg,

View file

@ -8,7 +8,7 @@ import Swiper from 'react-native-swiper';
import {changeOpacity} from 'app/utils/theme';
export default class SwiperIos extends PureComponent {
export default class DrawerSwiper extends PureComponent {
static propTypes = {
children: PropTypes.node.isRequired,
onPageSelected: PropTypes.func,
@ -22,6 +22,12 @@ export default class SwiperIos extends PureComponent {
openDrawerOffset: 0
};
componentWillReceiveProps(nextProps) {
if (nextProps.openDrawerOffset !== this.props.openDrawerOffset && this.refs.swiper) {
this.refs.swiper.initialRender = true;
}
}
swiperPageSelected = (e, state, context) => {
this.props.onPageSelected(context.state.index);
};
@ -44,7 +50,7 @@ export default class SwiperIos extends PureComponent {
const pagination = {bottom: 0};
if (showTeams) {
pagination.bottom = 10;
pagination.bottom = 0;
}
// Get the dimensions here so when the orientation changes we get the right dimensions
@ -57,7 +63,7 @@ export default class SwiperIos extends PureComponent {
loop={false}
index={1}
onMomentumScrollEnd={this.swiperPageSelected}
paginationStyle={[{position: 'relative'}, pagination]}
paginationStyle={[{position: 'absolute'}, pagination]}
width={deviceWidth - openDrawerOffset}
height={deviceHeight}
style={{backgroundColor: theme.sidebarBg}}

View file

@ -1,6 +0,0 @@
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
// Used to leverage the platform specific components
import Swiper from './swiper';
export default Swiper;

View file

@ -1,53 +0,0 @@
// 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 {ViewPagerAndroid} from 'react-native';
export default class SwiperAndroid extends PureComponent {
static propTypes = {
children: PropTypes.node.isRequired,
onPageSelected: PropTypes.func,
showTeams: PropTypes.bool.isRequired,
theme: PropTypes.object.isRequired
};
static defaultProps = {
onPageSelected: () => true
};
swiperPageSelected = (event) => {
this.props.onPageSelected(event.nativeEvent.position);
};
showTeamsPage = () => {
this.refs.swiper.setPage(0);
this.props.onPageSelected(0);
};
resetPage = () => {
this.refs.swiper.setPageWithoutAnimation(1);
this.props.onPageSelected(1);
};
render() {
const {
children,
showTeams,
theme
} = this.props;
return (
<ViewPagerAndroid
ref='swiper'
style={{flex: 1, backgroundColor: theme.sidebarBg}}
initialPage={1}
scrollEnabled={showTeams}
onPageSelected={this.swiperPageSelected}
>
{children}
</ViewPagerAndroid>
);
}
}

View file

@ -12,7 +12,7 @@ export default class Drawer extends BaseDrawer {
};
// To fix the android onLayout issue give this a value of 100% as it does not need another one
getHeight = () => '100%';
getMainHeight = () => '100%';
processTapGestures = () => {
// Note that we explicitly don't support tap to open or double tap because I didn't copy them over

View file

@ -80,9 +80,9 @@ class FormattedText extends Component {
// approach allows messages to render with React Elements while
// keeping React's virtual diffing working properly.
nodes = formattedMessage.
split(tokenDelimiter).
filter((part) => Boolean(part)).
map((part) => elements[part] || part);
split(tokenDelimiter).
filter((part) => Boolean(part)).
map((part) => elements[part] || part);
} else {
nodes = [formattedMessage];
}

View file

@ -156,24 +156,24 @@ class Post extends PureComponent {
const {intl, navigator, post, theme} = this.props;
MaterialIcon.getImageSource('close', 20, theme.sidebarHeaderTextColor).
then((source) => {
navigator.showModal({
screen: 'AddReaction',
title: intl.formatMessage({id: 'mobile.post_info.add_reaction', defaultMessage: 'Add Reaction'}),
animated: true,
navigatorStyle: {
navBarTextColor: theme.sidebarHeaderTextColor,
navBarBackgroundColor: theme.sidebarHeaderBg,
navBarButtonColor: theme.sidebarHeaderTextColor,
screenBackgroundColor: theme.centerChannelBg
},
passProps: {
post,
closeButton: source,
onEmojiPress: this.handleAddReactionToPost
}
then((source) => {
navigator.showModal({
screen: 'AddReaction',
title: intl.formatMessage({id: 'mobile.post_info.add_reaction', defaultMessage: 'Add Reaction'}),
animated: true,
navigatorStyle: {
navBarTextColor: theme.sidebarHeaderTextColor,
navBarBackgroundColor: theme.sidebarHeaderBg,
navBarButtonColor: theme.sidebarHeaderTextColor,
screenBackgroundColor: theme.centerChannelBg
},
passProps: {
post,
closeButton: source,
onEmojiPress: this.handleAddReactionToPost
}
});
});
});
}
handleFailedPostPress = () => {

View file

@ -252,7 +252,7 @@ export default class PostBodyAdditionalContent extends PureComponent {
const isImage = isImageLink(link);
const isOpenGraph = Boolean(openGraphData && openGraphData.description);
if ((isImage && !isOpenGraph && !linkLoadError) || isYouTube) {
if (((isImage && !isOpenGraph) || isYouTube) && !linkLoadError) {
const embed = this.generateToggleableEmbed(isImage, isYouTube);
if (embed && (linkLoaded || isYouTube)) {
return embed;

View file

@ -130,6 +130,10 @@ export default class PostList extends PureComponent {
return this.renderPost(item);
};
getItem = (data, index) => data[index];
getItemCount = (data) => data.length;
renderPost = (post) => {
const {
isSearchResult,
@ -177,6 +181,8 @@ export default class PostList extends PureComponent {
{...refreshControl}
renderItem={this.renderItem}
theme={theme}
getItem={this.getItem}
getItemCount={this.getItemCount}
/>
);
}

View file

@ -10,7 +10,6 @@ export default class RadioButtonGroup extends PureComponent {
static propTypes = {
children: PropTypes.node.isRequired,
name: PropTypes.string.isRequired,
value: PropTypes.string,
onSelect: PropTypes.func
};
@ -19,26 +18,21 @@ export default class RadioButtonGroup extends PureComponent {
constructor(props) {
super(props);
if (props.value) {
this.state = {
selected: props.value
};
} else {
React.Children.map(this.props.children, (option) => {
if (option) {
const {
value,
checked
} = option.props;
this.selected = null;
React.Children.forEach(this.props.children, (option) => {
if (option) {
const {
value,
checked
} = option.props;
if (!this.state.selected && checked) {
this.state = {
selected: value
};
}
if (!this.state.selected && checked) {
this.selected = value;
}
});
}
}
});
this.state = {selected: this.selected};
}
get value() {

View file

@ -1,30 +0,0 @@
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import React from 'react';
import {SectionList} from 'react-native';
import MetroListView from 'react-native/Libraries/Lists/MetroListView';
import VirtualizedSectionList from './virtualized_section_list';
export default class ScrollableSectionList extends SectionList {
getWrapperRef = () => {
return this._wrapperListRef; //eslint-disable-line no-underscore-dangle
};
render() {
const List = this.props.legacyImplementation ?
MetroListView :
VirtualizedSectionList;
return (
<List
{...this.props}
ref={this._captureRef} //eslint-disable-line no-underscore-dangle
/>
);
}
_wrapperListRef: MetroListView | VirtualizedSectionList<any>; //eslint-disable-line no-underscore-dangle
_captureRef = (ref) => {
this._wrapperListRef = ref; //eslint-disable-line no-underscore-dangle
};
}

View file

@ -1,26 +0,0 @@
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import React from 'react';
import {VirtualizedList} from 'react-native';
import VirtualizedSectionList from 'react-native/Libraries/Lists/VirtualizedSectionList';
export default class VirtualizedScrollableSectionList extends VirtualizedSectionList {
getListRef() {
return this._listRef; //eslint-disable-line no-underscore-dangle
}
render() {
return (
<VirtualizedList
{...this.state.childProps}
ref={this._captureRef} //eslint-disable-line no-underscore-dangle
/>
);
}
_listRef: VirtualizedList;
_captureRef = (ref) => {
this._listRef = ref; //eslint-disable-line no-underscore-dangle
};
}

View file

@ -51,7 +51,7 @@ export default class SearchBarAndroid extends PureComponent {
backArrowSize: 24,
deleteIconSize: 16,
searchIconSize: 16,
blurOnSubmit: false,
blurOnSubmit: true,
placeholder: 'Search',
showCancelButton: true,
placeholderTextColor: changeOpacity('#000', 0.5),

View file

@ -47,7 +47,8 @@ export default class SearchBarIos extends Component {
onChangeText: () => true,
onFocus: () => true,
onBlur: () => true,
onSelectionChange: () => true
onSelectionChange: () => true,
blurOnSubmit: true
};
cancel = () => {

View file

@ -15,6 +15,7 @@ export default {
}
});
},
clearListeners: () => true,
authenticate: LocalAuth.authenticate,
blurAppScreen: MattermostManaged.blurAppScreen,
getConfig: MattermostManaged.getConfig,

View file

@ -1,19 +1,27 @@
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import {NativeModules, NativeEventEmitter} from 'react-native';
import {NativeModules, DeviceEventEmitter} from 'react-native';
import LocalAuth from 'react-native-local-auth';
import JailMonkey from 'jail-monkey';
const {BlurAppScreen, MattermostManaged} = NativeModules;
const MattermostManagedEvents = new NativeEventEmitter(MattermostManaged);
const listeners = [];
export default {
addEventListener: (name, callback) => {
MattermostManagedEvents.addListener(name, (config) => {
const listener = DeviceEventEmitter.addListener(name, (config) => {
if (callback && typeof callback === 'function') {
callback(config);
}
});
listeners.push(listener);
},
clearListeners: () => {
listeners.forEach((listener) => {
listener.remove();
});
},
authenticate: LocalAuth.authenticate,
blurAppScreen: BlurAppScreen.enabled,

View file

@ -70,17 +70,17 @@ class PushNotification {
if (options.popInitialNotification) {
PendingNotifications.getInitialNotification().
then((notification) => {
if (notification) {
const data = notification.getData();
if (data) {
this.handleNotification(data, true);
then((notification) => {
if (notification) {
const data = notification.getData();
if (data) {
this.handleNotification(data, true);
}
}
}
}).
catch((err) => {
console.log('Android getInitialNotifiation() failed', err); //eslint-disable-line no-console
});
}).
catch((err) => {
console.log('Android getInitialNotifiation() failed', err); //eslint-disable-line no-console
});
}
}

View file

@ -59,7 +59,7 @@ class Channel extends PureComponent {
componentWillMount() {
EventEmitter.on('leave_team', this.handleLeaveTeam);
NetInfo.isConnected.addEventListener('change', this.handleConnectionChange);
NetInfo.isConnected.addEventListener('connectionChange', this.handleConnectionChange);
NetInfo.isConnected.fetch().then(this.handleConnectionChange);
if (this.props.currentTeam) {
@ -89,7 +89,7 @@ class Channel extends PureComponent {
const {closeWebSocket, stopPeriodicStatusUpdates} = this.props.actions;
EventEmitter.off('leave_team', this.handleLeaveTeam);
NetInfo.isConnected.removeEventListener('change', this.handleConnectionChange);
NetInfo.isConnected.removeEventListener('connectionChange', this.handleConnectionChange);
closeWebSocket();
stopPeriodicStatusUpdates();

View file

@ -262,7 +262,8 @@ const style = StyleSheet.create({
paddingHorizontal: 10,
position: 'absolute',
top: 0,
width: deviceWidth
width: deviceWidth,
overflow: 'hidden'
}
});

View file

@ -86,7 +86,7 @@ export default class Downloader extends PureComponent {
const res = await this.downloadTask;
const path = res.path();
const newPath = await CameraRoll.saveToCameraRoll(path);
const newPath = await CameraRoll.saveToCameraRoll(path, 'photo');
this.setState({
progress: 100

View file

@ -68,7 +68,7 @@ export default class ImagePreview extends PureComponent {
footerOpacity: new Animated.Value(1),
pagingEnabled: true,
showFileInfo: true,
wrapperViewOpacity: new Animated.Value(Platform.OS === 'android' ? 0 : 1)
wrapperViewOpacity: new Animated.Value(0)
};
}
@ -86,24 +86,13 @@ export default class ImagePreview extends PureComponent {
componentDidMount() {
Orientation.unlockAllOrientations();
// TODO: Use contentOffset on Android once PR is merged
// This is a hack until this PR gets merged: https://github.com/facebook/react-native/pull/12502
// On Android there is a render animation for scrollViews. In order for scrollTo to work
// on scrollViews we have to wait for the animation to finish. This will cause a bad flicker when we
// want to set the offset of the scrollView to show say the second file of a post with 3 files.
// Using this delayed opacity animation allows us to wait for the scrollView animation to finish,
// scollTo the correct offset for the chosen file, and then fade in like the component does on iOS.
if (Platform.OS === 'android') {
InteractionManager.runAfterInteractions(() => {
this.scrollView.scrollTo({x: (this.state.currentFile) * this.state.deviceWidth, animated: false});
Animated.timing(this.state.wrapperViewOpacity, {
toValue: 1,
duration: 200,
delay: 75
}).start();
});
}
InteractionManager.runAfterInteractions(() => {
this.scrollView.scrollTo({x: (this.state.currentFile) * this.state.deviceWidth, animated: false});
Animated.timing(this.state.wrapperViewOpacity, {
toValue: 1,
duration: 100
}).start();
});
}
componentWillUnmount() {
@ -176,9 +165,11 @@ export default class ImagePreview extends PureComponent {
};
handleScroll = (event) => {
if (event.nativeEvent.contentOffset.x % this.state.deviceWidth === 0) {
const offset = event.nativeEvent.contentOffset.x / this.state.deviceWidth;
const wholeNumber = Number((offset).toFixed(0));
if (Math.abs(offset - wholeNumber) < 0.01) {
this.setState({
currentFile: (event.nativeEvent.contentOffset.x / this.state.deviceWidth),
currentFile: wholeNumber,
pagingEnabled: true,
shouldShrinkImages: false
});
@ -340,8 +331,8 @@ export default class ImagePreview extends PureComponent {
pagingEnabled={!this.state.isZooming}
bounces={false}
onScroll={this.handleScroll}
scrollEventThrottle={1}
contentOffset={{x: (this.state.currentFile) * this.state.deviceWidth}}
scrollEventThrottle={2}
>
{this.props.files.map((file, index) => {
let component;

View file

@ -5,9 +5,9 @@
import React, {Component} from 'react';
import PropTypes from 'prop-types';
import {
Animated,
View,
PanResponder
Animated,
View,
PanResponder
} from 'react-native';
const {Image: AnimatedImage} = Animated;
@ -152,7 +152,7 @@ export default class ImageView extends Component {
setZoom = (zoom = true) => {
const zoomScale = zoom ? this.props.maximumZoomScale : this.props.minimumZoomScale;
const offsetByZoom = calcOffsetByZoom(this.state.width, this.state.height,
this.props.wrapperWidth, this.props.wrapperHeight, zoomScale);
this.props.wrapperWidth, this.props.wrapperHeight, zoomScale);
this.setState({
zoom: zoomScale,
@ -189,7 +189,7 @@ export default class ImageView extends Component {
});
} else {
const offsetByZoom = calcOffsetByZoom(this.state.width, this.state.height,
this.props.wrapperWidth, this.props.wrapperHeight, this.state.zoom);
this.props.wrapperWidth, this.props.wrapperHeight, this.state.zoom);
this.setState({
isZooming: true,
initialDistance: distance,

View file

@ -81,6 +81,10 @@ export default class Previewer extends Component {
});
}
componentDidMount() {
this.mounted = true;
}
componentWillReceiveProps(nextProps) {
if (this.props.shrink && !nextProps.shrink) {
this.setShrink();
@ -89,6 +93,10 @@ export default class Previewer extends Component {
}
}
componentWillUnmount() {
this.mounted = false;
}
setShrink = (shrink = false) => {
const {gutter, imageHeight, imageWidth} = this.props;
@ -187,6 +195,10 @@ export default class Previewer extends Component {
};
handleZoom = (zoom) => {
if (!this.mounted) {
return;
}
this.setState({
isZooming: zoom
});

View file

@ -8,6 +8,7 @@ import {
Dimensions,
Keyboard,
Platform,
SectionList,
StyleSheet,
Text,
TouchableHighlight,
@ -23,7 +24,6 @@ import Autocomplete from 'app/components/autocomplete';
import FormattedText from 'app/components/formatted_text';
import Loading from 'app/components/loading';
import Post from 'app/components/post';
import SectionList from 'app/components/scrollable_section_list';
import SearchBar from 'app/components/search_bar';
import SearchPreview from 'app/components/search_preview';
import StatusBar from 'app/components/status_bar';
@ -100,7 +100,7 @@ class Search extends Component {
if (shouldScroll && !this.state.isFocused) {
setTimeout(() => {
this.refs.list.getWrapperRef().getListRef().scrollToOffset({
this.refs.list._wrapperListRef.getListRef().scrollToOffset({ //eslint-disable-line no-underscore-dangle
animated: true,
offset: SECTION_HEIGHT + (2 * MODIFIER_LABEL_HEIGHT) + (recentLenght * RECENT_LABEL_HEIGHT) + ((recentLenght + 1) * RECENT_SEPARATOR_HEIGHT)
});
@ -385,7 +385,7 @@ class Search extends Component {
};
scrollToTop = () => {
this.refs.list.getWrapperRef().getListRef().scrollToOffset({
this.refs.list._wrapperListRef.getListRef().scrollToOffset({ //eslint-disable-line no-underscore-dangle
animated: false,
offset: 0
});

View file

@ -36,7 +36,7 @@ export default class NotificationSettingsEmail extends PureComponent {
const notifyProps = currentUser.notify_props || {};
props.navigator.setOnNavigatorEvent(this.onNavigatorEvent);
this.setStateFromNotifyProps(notifyProps);
this.state = this.setStateFromNotifyProps(notifyProps);
}
onNavigatorEvent = (event) => {
@ -76,12 +76,10 @@ export default class NotificationSettingsEmail extends PureComponent {
}
}
const newState = {
return {
...notifyProps,
interval
};
this.state = {...newState};
};
saveUserNotifyProps = () => {

View file

@ -23,7 +23,7 @@ export default class NotificationSettingsMentionsBase extends PureComponent {
props.navigator.setOnNavigatorEvent(this.onNavigatorEvent);
this.goingBack = true; //use to identify if the navigator is popping this screen
this.setStateFromNotifyProps(notifyProps);
this.state = this.setStateFromNotifyProps(notifyProps);
}
onNavigatorEvent = (event) => {
@ -56,7 +56,8 @@ export default class NotificationSettingsMentionsBase extends PureComponent {
this.keywords = newState.mention_keys;
this.replyValue = comments;
this.state = {...newState};
return newState;
};
toggleFirstNameMention = () => {

View file

@ -88,16 +88,16 @@ export default class NotificationSettingsMobileBase extends PureComponent {
saveUserNotifyProps = () => {
const {
channel,
comments,
desktop,
desktop_duration,
email,
first_name,
mention_keys,
push,
push_status
} = this.state;
channel,
comments,
desktop,
desktop_duration,
email,
first_name,
mention_keys,
push,
push_status
} = this.state;
this.props.onBack({
channel,

View file

@ -15,7 +15,6 @@
00E356F31AD99517003FC87E /* MattermostTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* MattermostTests.m */; };
0111A42B7F264BCF8CBDE3ED /* OpenSans-ExtraBoldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = FBBEC29EE2D3418D9AC33BD5 /* OpenSans-ExtraBoldItalic.ttf */; };
0C0D24F53F254F75869E5951 /* OpenSans-Italic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 41F3AFE83AAF4B74878AB78A /* OpenSans-Italic.ttf */; };
10CD747CE4304BD6AB38B4CD /* libRNDeviceInfo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EE671DF7637347CD8C069819 /* libRNDeviceInfo.a */; };
133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; };
139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */; };
139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */; };
@ -24,55 +23,57 @@
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
140ED2AC1D01E1AD002B40FF /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; };
146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; };
1B5204C4347D45A9A7AC3EA5 /* libReactNativeExceptionHandler.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A22BC320BA04E18A7F2A4E6 /* libReactNativeExceptionHandler.a */; };
1BCA51319AC6442991C6A208 /* Zocial.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0A091BF1A3D04650AD306A0D /* Zocial.ttf */; };
1C1F002AC5DE465FAE9E0D74 /* libFastImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C0C75A424714EAC8E876A8F /* libFastImage.a */; };
2B2679D44CFA48E6A60D68BC /* libRNFetchBlob.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B19E38FBCB94C57BB03B8E6 /* libRNFetchBlob.a */; };
2A167658767AAB5161E3271B /* libPods-Mattermost.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 65FD5EA57EBAE06106094B2F /* libPods-Mattermost.a */; };
2B4C9B708010475DA575B81D /* SimpleLineIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = F1F071EE85494E269A50AE88 /* SimpleLineIcons.ttf */; };
2D5296A8926B4D7FBAF2D6E2 /* OpenSans-Light.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 6561AEAC21CC40B8A72ABB93 /* OpenSans-Light.ttf */; };
2E3655C7E15049DBBC3A666B /* libRNImagePicker.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DFE628F5A526417D85AD635E /* libRNImagePicker.a */; };
374634801E8480C2005E1244 /* libRCTOrientation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 374634671E848085005E1244 /* libRCTOrientation.a */; };
375218501F4B9EE70035444B /* libRCTCameraRoll.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3752184F1F4B9E980035444B /* libRCTCameraRoll.a */; };
37ABD3C81F4CE142001FDE6B /* libART.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 37ABD39C1F4CE13B001FDE6B /* libART.a */; };
382D94CF15EE4FC292C3F341 /* Foundation.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 51F5A483EA9F4A9A87ACFB59 /* Foundation.ttf */; };
38FB8B0A3AAD4F839EF6EF0B /* libJailMonkey.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 77810F0A063349439B0D8B6B /* libJailMonkey.a */; };
3D38ABA732A34A9BB3294F90 /* EvilIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 349FBA7338E74D9BBD709528 /* EvilIcons.ttf */; };
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 */; };
7F2691A11EE1DC6A007574FE /* libRNNotifications.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F2691A01EE1DC51007574FE /* libRNNotifications.a */; };
7F292A711E8AB73400A450A3 /* SplashScreenResource in Resources */ = {isa = PBXBuildFile; fileRef = 7F292A701E8AB73400A450A3 /* SplashScreenResource */; };
7F292AA61E8ABB1100A450A3 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7F292AA41E8ABB1100A450A3 /* LaunchScreen.xib */; };
7F292AA71E8ABB1100A450A3 /* splash.png in Resources */ = {isa = PBXBuildFile; fileRef = 7F292AA51E8ABB1100A450A3 /* splash.png */; };
7F43D5A01F6BF882001FC614 /* libRNDeviceInfo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 37DD11281E79EBE1004111BA /* libRNDeviceInfo.a */; };
7F43D5D61F6BF8C2001FC614 /* libRNLocalAuth.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F8C49871F3DFC30003A22BA /* libRNLocalAuth.a */; };
7F43D5D71F6BF8D0001FC614 /* libRNPasscodeStatus.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F8C49F81F3E0710003A22BA /* libRNPasscodeStatus.a */; };
7F43D5D81F6BF8E9001FC614 /* libJailMonkey.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F8C4A621F3E21FB003A22BA /* libJailMonkey.a */; };
7F43D5D91F6BF8F4001FC614 /* libFastImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F8AAB3C1F4E0FEB00F5A52C /* libFastImage.a */; };
7F43D5DA1F6BF92C001FC614 /* libRNFetchBlob.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 375218411F4B9E320035444B /* libRNFetchBlob.a */; };
7F43D5DB1F6BF93B001FC614 /* libReactNativeExceptionHandler.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7FA7950B1F61A1A500C02924 /* libReactNativeExceptionHandler.a */; };
7F43D5DC1F6BF946001FC614 /* libRNSentry.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7FA795061F61A1A500C02924 /* libRNSentry.a */; };
7F43D5DD1F6BF95F001FC614 /* libRNCookieManagerIOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 372E25671F5F0E1800A2BFAB /* libRNCookieManagerIOS.a */; };
7F43D5DE1F6BF96A001FC614 /* libRCTYouTube.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F43D5BE1F6BF882001FC614 /* libRCTYouTube.a */; };
7F43D5E01F6BF994001FC614 /* libRNSVG.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F43D5DF1F6BF994001FC614 /* libRNSVG.a */; };
7F43D6061F6BF9EB001FC614 /* libPods-Mattermost.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F43D6051F6BF9EB001FC614 /* libPods-Mattermost.a */; };
7F43D63F1F6BFA19001FC614 /* libBVLinearGradient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 37D8FEC21E80B5230091F3BD /* libBVLinearGradient.a */; };
7F43D6401F6BFA82001FC614 /* libRCTPushNotification.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F63D2811E6C957C001FAE12 /* libRCTPushNotification.a */; };
7F6877B31E7836070094B63F /* libToolTipMenu.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F6877B01E7835E50094B63F /* libToolTipMenu.a */; };
7FBB5E9A1E1F5A4B000DE18A /* libRNSVG.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7FDF28E11E1F4B1F00DBBE56 /* libRNSVG.a */; };
7FBB5E9B1E1F5A4B000DE18A /* libRNVectorIcons.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7FDF290C1E1F4B4E00DBBE56 /* libRNVectorIcons.a */; };
7FC200E81EBB65370099331B /* libReactNativeNavigation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7FC200DF1EBB65100099331B /* libReactNativeNavigation.a */; };
7FEB10981F6101710039A015 /* BlurAppScreen.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FEB10971F6101710039A015 /* BlurAppScreen.m */; };
7FEB109D1F61019C0039A015 /* MattermostManaged.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FEB109A1F61019C0039A015 /* MattermostManaged.m */; };
7FEB109E1F61019C0039A015 /* UIImage+ImageEffects.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FEB109C1F61019C0039A015 /* UIImage+ImageEffects.m */; };
7FED0C321E7C4AAC001A7CCA /* libRNCookieManagerIOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F906D971E6A1ADF00B8F49A /* libRNCookieManagerIOS.a */; };
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
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 */; };
D719A67137964F08BE47A5FC /* OpenSans-ExtraBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 3647DF63D6764CF093375861 /* OpenSans-ExtraBold.ttf */; };
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 */
/* Begin PBXContainerItemProxy section */
@ -139,6 +140,13 @@
remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192;
remoteInfo = React;
};
372E25661F5F0E1800A2BFAB /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 62A58E5E984E4CF1811620B8 /* RNCookieManagerIOS.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 1BD725DA1CF77A8B005DBD79;
remoteInfo = RNCookieManagerIOS;
};
374634661E848085005E1244 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 5C3B95629BA74FB3A8377CB7 /* RCTOrientation.xcodeproj */;
@ -160,13 +168,6 @@
remoteGlobalIDString = 58B5115D1A9E6B3D00147676;
remoteInfo = RCTCameraRoll;
};
3779BE9F1EB1235400D081C1 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 85E82BCA0FD245EEA520D106 /* RNImagePicker.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 014A3B5C1C6CF33500B6D375;
remoteInfo = RNImagePicker;
};
37ABD39B1F4CE13B001FDE6B /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 37ABD3971F4CE13B001FDE6B /* ART.xcodeproj */;
@ -188,6 +189,48 @@
remoteGlobalIDString = DA5891D81BA9A9FC002B4DB2;
remoteInfo = RNDeviceInfo;
};
37DF8AC81F5F0D430079BF89 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 37ABD3971F4CE13B001FDE6B /* ART.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 323A12871E5F266B004975B8;
remoteInfo = "ART-tvOS";
};
37DF8ACC1F5F0D430079BF89 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 7DCC3D826CE640AF8F491692 /* BVLinearGradient.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 64AA15081EF7F30100718508;
remoteInfo = "BVLinearGradient-tvOS";
};
37DF8AF11F5F0D430079BF89 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 139D7ECE1E25DB7D00323FB7;
remoteInfo = "third-party";
};
37DF8AF31F5F0D430079BF89 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 3D383D3C1EBD27B6005632C8;
remoteInfo = "third-party-tvOS";
};
37DF8AF51F5F0D430079BF89 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 139D7E881E25C6D100323FB7;
remoteInfo = "double-conversion";
};
37DF8AF71F5F0D430079BF89 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 3D383D621EBD27B9005632C8;
remoteInfo = "double-conversion-tvOS";
};
3DAD3E831DF850E9000B6D8A /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */;
@ -307,6 +350,20 @@
remoteGlobalIDString = 134814201AA4EA6300B7C361;
remoteInfo = RNNotifications;
};
7F43D5BD1F6BF882001FC614 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = A2968536BEC74A4ABBB73BD9 /* RCTYouTube.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 8BDB9BC91B4289AE00EF9FEF;
remoteInfo = RCTYouTube;
};
7F43D63A1F6BF9EB001FC614 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 2CBE9C0FB56E4FDA96C30792 /* RNSVG.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 7F43D6041F6BF9CA001FC614;
remoteInfo = "RNSVG-tvOS";
};
7F63D2801E6C957C001FAE12 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 7F63D27B1E6C957C001FAE12 /* RCTPushNotification.xcodeproj */;
@ -363,20 +420,6 @@
remoteGlobalIDString = 38C138441D3FC3F600A8162D;
remoteInfo = JailMonkey;
};
7F906D961E6A1ADF00B8F49A /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 31A0780E2F224AC8AF8E6930 /* RNCookieManagerIOS.xcodeproj */;
proxyType = 2;
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 */;
@ -463,7 +506,6 @@
2B25899FDAC149EB96ED3305 /* 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>"; };
2CBE9C0FB56E4FDA96C30792 /* RNSVG.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNSVG.xcodeproj; path = "../node_modules/react-native-svg/ios/RNSVG.xcodeproj"; sourceTree = "<group>"; };
2DCFD31D3F4A4154822AB532 /* 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>"; };
31A0780E2F224AC8AF8E6930 /* RNCookieManagerIOS.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNCookieManagerIOS.xcodeproj; path = "../node_modules/react-native-cookies/RNCookieManagerIOS.xcodeproj"; sourceTree = "<group>"; };
32AC3D4EA79E44738A6E9766 /* OpenSans-BoldItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "OpenSans-BoldItalic.ttf"; path = "../assets/fonts/OpenSans-BoldItalic.ttf"; sourceTree = "<group>"; };
349FBA7338E74D9BBD709528 /* 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>"; };
356C9186FA374641A00EB2EA /* MaterialIcons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = MaterialIcons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/MaterialIcons.ttf"; sourceTree = "<group>"; };
@ -482,9 +524,11 @@
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>"; };
62A58E5E984E4CF1811620B8 /* RNCookieManagerIOS.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNCookieManagerIOS.xcodeproj; path = "../node_modules/react-native-cookies/ios/RNCookieManagerIOS.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; };
7535D128F00C4A47A182627E /* libRNCookieManagerIOS.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNCookieManagerIOS.a; sourceTree = "<group>"; };
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>"; };
@ -493,6 +537,8 @@
7F292A701E8AB73400A450A3 /* SplashScreenResource */ = {isa = PBXFileReference; lastKnownFileType = folder; path = SplashScreenResource; sourceTree = "<group>"; };
7F292AA41E8ABB1100A450A3 /* LaunchScreen.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = LaunchScreen.xib; path = SplashScreenResource/LaunchScreen.xib; sourceTree = "<group>"; };
7F292AA51E8ABB1100A450A3 /* splash.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = splash.png; path = SplashScreenResource/splash.png; sourceTree = "<group>"; };
7F43D5DF1F6BF994001FC614 /* libRNSVG.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libRNSVG.a; path = "../../../../../../../Library/Developer/Xcode/DerivedData/Mattermost-czlinsdviifujheezzjvmisotjrm/Build/Products/Debug-iphonesimulator/libRNSVG.a"; sourceTree = "<group>"; };
7F43D6051F6BF9EB001FC614 /* libPods-Mattermost.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libPods-Mattermost.a"; path = "../../../../../../../Library/Developer/Xcode/DerivedData/Mattermost-czlinsdviifujheezzjvmisotjrm/Build/Products/Debug-iphonesimulator/libPods-Mattermost.a"; sourceTree = "<group>"; };
7F63D27B1E6C957C001FAE12 /* RCTPushNotification.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTPushNotification.xcodeproj; path = "../node_modules/react-native/Libraries/PushNotificationIOS/RCTPushNotification.xcodeproj"; sourceTree = "<group>"; };
7F63D2C21E6DD98A001FAE12 /* Mattermost.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = Mattermost.entitlements; path = Mattermost/Mattermost.entitlements; sourceTree = "<group>"; };
7F6877AA1E7835E50094B63F /* ToolTipMenu.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ToolTipMenu.xcodeproj; path = "../node_modules/react-native-tooltip/ToolTipMenu.xcodeproj"; sourceTree = "<group>"; };
@ -504,9 +550,7 @@
7FEB109B1F61019C0039A015 /* UIImage+ImageEffects.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIImage+ImageEffects.h"; path = "Mattermost/UIImage+ImageEffects.h"; sourceTree = "<group>"; };
7FEB109C1F61019C0039A015 /* UIImage+ImageEffects.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIImage+ImageEffects.m"; path = "Mattermost/UIImage+ImageEffects.m"; sourceTree = "<group>"; };
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = "<group>"; };
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>"; };
@ -518,7 +562,6 @@
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>"; };
DFE628F5A526417D85AD635E /* libRNImagePicker.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNImagePicker.a; sourceTree = "<group>"; };
EBA6063A99C141098D40C67A /* RNPasscodeStatus.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNPasscodeStatus.xcodeproj; path = "../node_modules/react-native-passcode-status/ios/RNPasscodeStatus.xcodeproj"; sourceTree = "<group>"; };
EDC04CBCF81642219D199CBB /* Octicons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Octicons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/Octicons.ttf"; sourceTree = "<group>"; };
EE3EE4548D3F4A49B1274722 /* libRNLocalAuth.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNLocalAuth.a; sourceTree = "<group>"; };
@ -543,7 +586,7 @@
files = (
37ABD3C81F4CE142001FDE6B /* libART.a in Frameworks */,
375218501F4B9EE70035444B /* libRCTCameraRoll.a in Frameworks */,
7FBB5E9A1E1F5A4B000DE18A /* libRNSVG.a in Frameworks */,
7F43D5E01F6BF994001FC614 /* libRNSVG.a in Frameworks */,
7FBB5E9B1E1F5A4B000DE18A /* libRNVectorIcons.a in Frameworks */,
5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */,
146834051AC3E58100842450 /* libReact.a in Frameworks */,
@ -557,23 +600,24 @@
374634801E8480C2005E1244 /* libRCTOrientation.a in Frameworks */,
00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */,
139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */,
7FED0C321E7C4AAC001A7CCA /* libRNCookieManagerIOS.a in Frameworks */,
10CD747CE4304BD6AB38B4CD /* libRNDeviceInfo.a in Frameworks */,
584837D6B55F405F908A2053 /* libBVLinearGradient.a in Frameworks */,
7F43D5A01F6BF882001FC614 /* libRNDeviceInfo.a in Frameworks */,
7F43D63F1F6BFA19001FC614 /* libBVLinearGradient.a in Frameworks */,
7F6877B31E7836070094B63F /* libToolTipMenu.a in Frameworks */,
2E3655C7E15049DBBC3A666B /* libRNImagePicker.a in Frameworks */,
7FC200E81EBB65370099331B /* libReactNativeNavigation.a in Frameworks */,
7F2691A11EE1DC6A007574FE /* libRNNotifications.a in Frameworks */,
615D2E7805814A3A9B9C69EC /* libRNLocalAuth.a in Frameworks */,
FDEF24E9D9AB47728E11033B /* libRNPasscodeStatus.a in Frameworks */,
38FB8B0A3AAD4F839EF6EF0B /* libJailMonkey.a in Frameworks */,
1C1F002AC5DE465FAE9E0D74 /* libFastImage.a in Frameworks */,
2B2679D44CFA48E6A60D68BC /* libRNFetchBlob.a in Frameworks */,
1B5204C4347D45A9A7AC3EA5 /* libReactNativeExceptionHandler.a in Frameworks */,
CB1B312483534997BEE7E65E /* libRNSentry.a in Frameworks */,
7F43D5D61F6BF8C2001FC614 /* libRNLocalAuth.a in Frameworks */,
7F43D5D71F6BF8D0001FC614 /* libRNPasscodeStatus.a in Frameworks */,
7F43D5D81F6BF8E9001FC614 /* libJailMonkey.a in Frameworks */,
7F43D5D91F6BF8F4001FC614 /* libFastImage.a in Frameworks */,
7F43D5DA1F6BF92C001FC614 /* libRNFetchBlob.a in Frameworks */,
7F43D5DB1F6BF93B001FC614 /* libReactNativeExceptionHandler.a in Frameworks */,
7F43D5DC1F6BF946001FC614 /* libRNSentry.a in Frameworks */,
DEBCF44F1F46413BB407D316 /* libz.tbd in Frameworks */,
5F190C97C28E4E5E93D933C0 /* libRCTYouTube.a in Frameworks */,
A14B2A56A554E84DFE3D6580 /* libPods-Mattermost.a in Frameworks */,
7F43D5DD1F6BF95F001FC614 /* libRNCookieManagerIOS.a in Frameworks */,
7F43D6401F6BFA82001FC614 /* libRCTPushNotification.a in Frameworks */,
7F43D5DE1F6BF96A001FC614 /* libRCTYouTube.a in Frameworks */,
7F43D6061F6BF9EB001FC614 /* libPods-Mattermost.a in Frameworks */,
2A167658767AAB5161E3271B /* libPods-Mattermost.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -717,6 +761,18 @@
3DAD3EAB1DF850E9000B6D8A /* libcxxreact.a */,
3DAD3EAD1DF850E9000B6D8A /* libjschelpers.a */,
3DAD3EAF1DF850E9000B6D8A /* libjschelpers.a */,
37DF8AF21F5F0D430079BF89 /* libthird-party.a */,
37DF8AF41F5F0D430079BF89 /* libthird-party.a */,
37DF8AF61F5F0D430079BF89 /* libdouble-conversion.a */,
37DF8AF81F5F0D430079BF89 /* libdouble-conversion.a */,
);
name = Products;
sourceTree = "<group>";
};
372E25631F5F0E1800A2BFAB /* Products */ = {
isa = PBXGroup;
children = (
372E25671F5F0E1800A2BFAB /* libRNCookieManagerIOS.a */,
);
name = Products;
sourceTree = "<group>";
@ -745,18 +801,11 @@
name = Products;
sourceTree = "<group>";
};
3779BE7C1EB1235400D081C1 /* Products */ = {
isa = PBXGroup;
children = (
3779BEA01EB1235400D081C1 /* libRNImagePicker.a */,
);
name = Products;
sourceTree = "<group>";
};
37ABD3981F4CE13B001FDE6B /* Products */ = {
isa = PBXGroup;
children = (
37ABD39C1F4CE13B001FDE6B /* libART.a */,
37DF8AC91F5F0D430079BF89 /* libART-tvOS.a */,
);
name = Products;
sourceTree = "<group>";
@ -765,6 +814,7 @@
isa = PBXGroup;
children = (
37D8FEC21E80B5230091F3BD /* libBVLinearGradient.a */,
37DF8ACD1F5F0D430079BF89 /* libBVLinearGradient.a */,
);
name = Products;
sourceTree = "<group>";
@ -777,9 +827,29 @@
name = Products;
sourceTree = "<group>";
};
37DF8AC51F5F0D410079BF89 /* Recovered References */ = {
isa = PBXGroup;
children = (
EE671DF7637347CD8C069819 /* libRNDeviceInfo.a */,
ACC6B9FDC0AD45A6BFA4FBCD /* libBVLinearGradient.a */,
EE3EE4548D3F4A49B1274722 /* libRNLocalAuth.a */,
17A75F5A3D0D4A4A995DCD76 /* libRNPasscodeStatus.a */,
77810F0A063349439B0D8B6B /* libJailMonkey.a */,
0C0C75A424714EAC8E876A8F /* libFastImage.a */,
4B19E38FBCB94C57BB03B8E6 /* libRNFetchBlob.a */,
4A22BC320BA04E18A7F2A4E6 /* libReactNativeExceptionHandler.a */,
2AE23B96BF7545B9A77C0C87 /* libRNSentry.a */,
8606EB1EB7E349EF8248933E /* libz.tbd */,
7535D128F00C4A47A182627E /* libRNCookieManagerIOS.a */,
);
name = "Recovered References";
sourceTree = "<group>";
};
4B992D7BAAEDF8759DB525B5 /* Frameworks */ = {
isa = PBXGroup;
children = (
7F43D6051F6BF9EB001FC614 /* libPods-Mattermost.a */,
7F43D5DF1F6BF994001FC614 /* libRNSVG.a */,
65FD5EA57EBAE06106094B2F /* libPods-Mattermost.a */,
4246DC09024BB33A3E491E25 /* libPods-MattermostTests.a */,
);
@ -823,6 +893,14 @@
name = Products;
sourceTree = "<group>";
};
7F43D58F1F6BF855001FC614 /* Products */ = {
isa = PBXGroup;
children = (
7F43D5BE1F6BF882001FC614 /* libRCTYouTube.a */,
);
name = Products;
sourceTree = "<group>";
};
7F63D27C1E6C957C001FAE12 /* Products */ = {
isa = PBXGroup;
children = (
@ -873,22 +951,6 @@
name = Products;
sourceTree = "<group>";
};
7F906D7A1E6A1ADF00B8F49A /* Products */ = {
isa = PBXGroup;
children = (
7F906D971E6A1ADF00B8F49A /* libRNCookieManagerIOS.a */,
);
name = Products;
sourceTree = "<group>";
};
7FA794CE1F61A1A400C02924 /* Products */ = {
isa = PBXGroup;
children = (
7FA794ED1F61A1A500C02924 /* libRCTYouTube.a */,
);
name = Products;
sourceTree = "<group>";
};
7FA795021F61A1A500C02924 /* Products */ = {
isa = PBXGroup;
children = (
@ -917,6 +979,7 @@
isa = PBXGroup;
children = (
7FDF28E11E1F4B1F00DBBE56 /* libRNSVG.a */,
7F43D63B1F6BF9EB001FC614 /* libRNSVG-tvOS.a */,
);
name = Products;
sourceTree = "<group>";
@ -951,11 +1014,9 @@
139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */,
2CBE9C0FB56E4FDA96C30792 /* RNSVG.xcodeproj */,
2B25899FDAC149EB96ED3305 /* RNVectorIcons.xcodeproj */,
31A0780E2F224AC8AF8E6930 /* RNCookieManagerIOS.xcodeproj */,
B97AA6F961BB47D3A3297E8E /* RNDeviceInfo.xcodeproj */,
7DCC3D826CE640AF8F491692 /* BVLinearGradient.xcodeproj */,
5C3B95629BA74FB3A8377CB7 /* RCTOrientation.xcodeproj */,
85E82BCA0FD245EEA520D106 /* RNImagePicker.xcodeproj */,
D0281D64B98143668D6AD42B /* RNLocalAuth.xcodeproj */,
EBA6063A99C141098D40C67A /* RNPasscodeStatus.xcodeproj */,
27A6EA89298440439DA9F98D /* JailMonkey.xcodeproj */,
@ -963,6 +1024,7 @@
546CB0A5BB8F453890CBA559 /* RNFetchBlob.xcodeproj */,
3B1E210BF3B649BBBF427977 /* ReactNativeExceptionHandler.xcodeproj */,
9552041247E749308CE7B412 /* RNSentry.xcodeproj */,
62A58E5E984E4CF1811620B8 /* RNCookieManagerIOS.xcodeproj */,
A2968536BEC74A4ABBB73BD9 /* RCTYouTube.xcodeproj */,
);
name = Libraries;
@ -986,6 +1048,7 @@
00E356EF1AD99517003FC87E /* MattermostTests */,
83CBBA001A601CBA00E9B192 /* Products */,
0156F464626F49C2977D7982 /* Resources */,
37DF8AC51F5F0D410079BF89 /* Recovered References */,
57D053CEA78013E949257E00 /* Pods */,
4B992D7BAAEDF8759DB525B5 /* Frameworks */,
);
@ -1154,7 +1217,7 @@
ProjectRef = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;
},
{
ProductGroup = 7FA794CE1F61A1A400C02924 /* Products */;
ProductGroup = 7F43D58F1F6BF855001FC614 /* Products */;
ProjectRef = A2968536BEC74A4ABBB73BD9 /* RCTYouTube.xcodeproj */;
},
{
@ -1170,8 +1233,8 @@
ProjectRef = 7FC200BC1EBB65100099331B /* ReactNativeNavigation.xcodeproj */;
},
{
ProductGroup = 7F906D7A1E6A1ADF00B8F49A /* Products */;
ProjectRef = 31A0780E2F224AC8AF8E6930 /* RNCookieManagerIOS.xcodeproj */;
ProductGroup = 372E25631F5F0E1800A2BFAB /* Products */;
ProjectRef = 62A58E5E984E4CF1811620B8 /* RNCookieManagerIOS.xcodeproj */;
},
{
ProductGroup = 37DD11071E79EBE1004111BA /* Products */;
@ -1181,10 +1244,6 @@
ProductGroup = 3752181C1F4B9E320035444B /* Products */;
ProjectRef = 546CB0A5BB8F453890CBA559 /* RNFetchBlob.xcodeproj */;
},
{
ProductGroup = 3779BE7C1EB1235400D081C1 /* Products */;
ProjectRef = 85E82BCA0FD245EEA520D106 /* RNImagePicker.xcodeproj */;
},
{
ProductGroup = 7F8C49621F3DFC30003A22BA /* Products */;
ProjectRef = D0281D64B98143668D6AD42B /* RNLocalAuth.xcodeproj */;
@ -1279,6 +1338,13 @@
remoteRef = 146834031AC3E56700842450 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
372E25671F5F0E1800A2BFAB /* libRNCookieManagerIOS.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRNCookieManagerIOS.a;
remoteRef = 372E25661F5F0E1800A2BFAB /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
374634671E848085005E1244 /* libRCTOrientation.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
@ -1300,13 +1366,6 @@
remoteRef = 3752184E1F4B9E980035444B /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
3779BEA01EB1235400D081C1 /* libRNImagePicker.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRNImagePicker.a;
remoteRef = 3779BE9F1EB1235400D081C1 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
37ABD39C1F4CE13B001FDE6B /* libART.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
@ -1328,6 +1387,48 @@
remoteRef = 37DD11271E79EBE1004111BA /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
37DF8AC91F5F0D430079BF89 /* libART-tvOS.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = "libART-tvOS.a";
remoteRef = 37DF8AC81F5F0D430079BF89 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
37DF8ACD1F5F0D430079BF89 /* libBVLinearGradient.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libBVLinearGradient.a;
remoteRef = 37DF8ACC1F5F0D430079BF89 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
37DF8AF21F5F0D430079BF89 /* libthird-party.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = "libthird-party.a";
remoteRef = 37DF8AF11F5F0D430079BF89 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
37DF8AF41F5F0D430079BF89 /* libthird-party.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = "libthird-party.a";
remoteRef = 37DF8AF31F5F0D430079BF89 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
37DF8AF61F5F0D430079BF89 /* libdouble-conversion.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = "libdouble-conversion.a";
remoteRef = 37DF8AF51F5F0D430079BF89 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
37DF8AF81F5F0D430079BF89 /* libdouble-conversion.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = "libdouble-conversion.a";
remoteRef = 37DF8AF71F5F0D430079BF89 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
3DAD3E841DF850E9000B6D8A /* libRCTImage-tvOS.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
@ -1447,6 +1548,20 @@
remoteRef = 7F26919F1EE1DC51007574FE /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
7F43D5BE1F6BF882001FC614 /* libRCTYouTube.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRCTYouTube.a;
remoteRef = 7F43D5BD1F6BF882001FC614 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
7F43D63B1F6BF9EB001FC614 /* libRNSVG-tvOS.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = "libRNSVG-tvOS.a";
remoteRef = 7F43D63A1F6BF9EB001FC614 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
7F63D2811E6C957C001FAE12 /* libRCTPushNotification.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
@ -1503,20 +1618,6 @@
remoteRef = 7F8C4A611F3E21FB003A22BA /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
7F906D971E6A1ADF00B8F49A /* libRNCookieManagerIOS.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRNCookieManagerIOS.a;
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;
@ -1784,7 +1885,7 @@
"-ObjC",
"-lc++",
);
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_BUNDLE_IDENTIFIER = com.mattermost.rnbeta;
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Mattermost.app/Mattermost";
};
@ -1809,7 +1910,7 @@
"-ObjC",
"-lc++",
);
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_BUNDLE_IDENTIFIER = com.mattermost.rnbeta;
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Mattermost.app/Mattermost";
};
@ -1831,7 +1932,6 @@
"$(SRCROOT)/../node_modules/react-native/Libraries/PushNotificationIOS/**",
"$(SRCROOT)/../node_modules/react-native-orientation/iOS/RCTOrientation/**",
"$(SRCROOT)/../node_modules/react-native-smart-splash-screen/ios/RCTSplashScreen/RCTSplashScreen/**",
"$(SRCROOT)/../node_modules/react-native-image-picker/ios",
"$(SRCROOT)/../node_modules/react-native-navigation/ios/**",
"$(SRCROOT)/../node_modules/react-native-notifications/RNNotifications/**",
"$(SRCROOT)/../node_modules/react-native-local-auth",
@ -1842,6 +1942,8 @@
"$(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-cookies/ios/RNCookieManagerIOS",
"$(SRCROOT)/../node_modules/react-native-image-picker/ios",
"$(SRCROOT)/../node_modules/react-native-youtube/**",
);
INFOPLIST_FILE = Mattermost/Info.plist;
@ -1875,7 +1977,6 @@
"$(SRCROOT)/../node_modules/react-native/Libraries/PushNotificationIOS/**",
"$(SRCROOT)/../node_modules/react-native-orientation/iOS/RCTOrientation/**",
"$(SRCROOT)/../node_modules/react-native-smart-splash-screen/ios/RCTSplashScreen/RCTSplashScreen/**",
"$(SRCROOT)/../node_modules/react-native-image-picker/ios",
"$(SRCROOT)/../node_modules/react-native-navigation/ios/**",
"$(SRCROOT)/../node_modules/react-native-notifications/RNNotifications/**",
"$(SRCROOT)/../node_modules/react-native-local-auth",
@ -1886,6 +1987,8 @@
"$(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-cookies/ios/RNCookieManagerIOS",
"$(SRCROOT)/../node_modules/react-native-image-picker/ios",
"$(SRCROOT)/../node_modules/react-native-youtube/**",
);
INFOPLIST_FILE = Mattermost/Info.plist;

View file

@ -19,7 +19,6 @@
#import "Orientation.h"
#import "RCCManager.h"
#import "RNNotifications.h"
#import "MattermostManaged.h"
@implementation AppDelegate

View file

@ -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.3.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>50</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>
<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.3.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>com.mattermost</string>
<key>CFBundleURLSchemes</key>
<array>
<string>mattermost</string>
</array>
</dict>
</array>
<key>CFBundleVersion</key>
<string>50</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></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/>
</dict>
</plist>

View file

@ -6,10 +6,10 @@
// See License.txt for license information.
//
#import <React/RCTEventEmitter.h>
#import <React/RCTBridgeModule.h>
@interface MattermostManaged : RCTEventEmitter
@interface MattermostManaged : NSObject <RCTBridgeModule>
+ (void)sendConfigChangedEvent;

View file

@ -6,6 +6,8 @@
// See License.txt for license information.
//
#import <React/RCTBridge.h>
#import <React/RCTEventDispatcher.h>
#import "RCTTextField.h"
#import "MattermostManaged.h"
@ -13,7 +15,17 @@
RCT_EXPORT_MODULE();
-(void)startObserving {
@synthesize bridge = _bridge;
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[[NSNotificationCenter defaultCenter] removeObserver:NSUserDefaultsDidChangeNotification];
}
- (void)setBridge:(RCTBridge *)bridge
{
_bridge = bridge;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(managedConfigDidChange:) name:@"managedConfigDidChange" object:nil];
[[NSNotificationCenter defaultCenter] addObserverForName:NSUserDefaultsDidChangeNotification
object:nil
@ -22,23 +34,12 @@ RCT_EXPORT_MODULE();
}];
}
- (void)stopObserving
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[[NSNotificationCenter defaultCenter] removeObserver:NSUserDefaultsDidChangeNotification];
}
+ (void)sendConfigChangedEvent {
[[NSNotificationCenter defaultCenter] postNotificationName:@"managedConfigDidChange"
object:self
userInfo:nil];
}
- (NSArray<NSString *> *)supportedEvents
{
return @[@"managedConfigDidChange"];
}
// The Managed app configuration dictionary pushed down from an MDM server are stored in this key.
static NSString * const configurationKey = @"com.apple.configuration.managed";
@ -49,12 +50,12 @@ static NSString * const feedbackKey = @"com.apple.feedback.managed";
- (void)managedConfigDidChange:(NSNotification *)notification
{
NSDictionary *response = [[NSUserDefaults standardUserDefaults] dictionaryForKey:configurationKey];
[self sendEventWithName:@"managedConfigDidChange" body:response];
[_bridge.eventDispatcher sendDeviceEventWithName:@"managedConfigDidChange" body:response];
}
- (void) remoteConfigChanged {
NSDictionary *response = [[NSUserDefaults standardUserDefaults] dictionaryForKey:configurationKey];
[self sendEventWithName:@"managedConfigDidChange" body:response];
[_bridge.eventDispatcher sendDeviceEventWithName:@"managedConfigDidChange" body:response];
}
RCT_EXPORT_METHOD(getConfig:(RCTPromiseResolveBlock)resolve

View file

@ -8,8 +8,8 @@ if [[ "${SENTRY_ENABLED}" = "true" ]]; then
./makeSentryProperties.sh
export SENTRY_PROPERTIES=sentry.properties
../node_modules/sentry-cli-binary/bin/sentry-cli react-native xcode ../node_modules/react-native/packager/react-native-xcode.sh
../node_modules/sentry-cli-binary/bin/sentry-cli react-native xcode ../node_modules/react-native/scripts/react-native-xcode.sh
else
echo "Sentry native integration is not enabled"
../node_modules/react-native/packager/react-native-xcode.sh
../node_modules/react-native/scripts/react-native-xcode.sh
fi

View file

@ -13,81 +13,83 @@
"commonmark-react-renderer": "hmhealey/commonmark-react-renderer#c5d00343664c89da40d5a2ffa8b083e7cc1615d7",
"deep-equal": "1.0.1",
"intl": "1.2.5",
"jail-monkey": "0.0.8",
"jail-monkey": "0.0.9",
"mattermost-redux": "mattermost/mattermost-redux#master",
"prop-types": "15.5.10",
"react": "16.0.0-alpha.6",
"react": "16.0.0-alpha.12",
"react-intl": "2.3.0",
"react-native": "0.44.0",
"react-native-animatable": "1.2.2",
"react-native-bottom-sheet": "1.0.1",
"react-native": "0.48.3",
"react-native-animatable": "1.2.3",
"react-native-bottom-sheet": "1.0.2",
"react-native-button": "1.8.2",
"react-native-circular-progress": "0.0.8",
"react-native-cookies": "3.1.0",
"react-native-cookies": "3.2.0",
"react-native-device-info": "0.11.0",
"react-native-drawer": "2.3.0",
"react-native-exception-handler": "2.0.1",
"react-native-drawer": "2.4.0",
"react-native-exception-handler": "2.1.0",
"react-native-fast-image": "1.0.0",
"react-native-fetch-blob": "0.10.8",
"react-native-image-picker": "jp928/react-native-image-picker#6ee35b69f3dbd6c7c66f580fd4d9eabf398703d4",
"react-native-keyboard-aware-scroll-view": "0.2.8",
"react-native-linear-gradient": "2.0.0",
"react-native-image-picker": "0.26.6",
"react-native-keyboard-aware-scroll-view": "0.3.0",
"react-native-linear-gradient": "2.3.0",
"react-native-local-auth": "enahum/react-native-local-auth.git",
"react-native-navigation": "1.1.216",
"react-native-notifications": "enahum/react-native-notifications.git",
"react-native-orientation": "enahum/react-native-orientation.git",
"react-native-passcode-status": "1.1.0",
"react-native-sentry": "0.14.5",
"react-native-sentry": "0.15.1",
"react-native-status-bar-size": "0.3.2",
"react-native-svg": "5.1.8",
"react-native-swiper": "1.5.4",
"react-native-svg": "5.4.1",
"react-native-swiper": "nixoz/react-native-swiper",
"react-native-tooltip": "enahum/react-native-tooltip",
"react-native-vector-icons": "4.1.1",
"react-native-vector-icons": "4.3.0",
"react-native-youtube": "1.0.0-beta.3",
"react-redux": "5.0.4",
"redux": "3.6.0",
"react-redux": "5.0.6",
"redux": "3.7.2",
"redux-batched-actions": "0.2.0",
"redux-persist": "4.8.0",
"redux-persist-transform-filter": "0.0.9",
"redux-persist": "4.9.1",
"redux-persist-transform-filter": "0.0.15",
"redux-thunk": "2.2.0",
"reselect": "3.0.1",
"semver": "5.3.0",
"semver": "5.4.1",
"socketcluster": "5.0.4",
"tinycolor2": "1.4.1",
"url-parse": "1.1.9",
"youtube-video-id": "0.0.2"
},
"devDependencies": {
"babel-cli": "6.24.1",
"babel-cli": "6.26.0",
"babel-eslint": "7.2.3",
"babel-plugin-module-resolver": "2.7.0",
"babel-plugin-module-resolver": "2.7.1",
"babel-preset-es2015": "6.24.1",
"babel-preset-latest": "6.24.1",
"babel-preset-react": "6.24.1",
"babel-preset-react-native": "1.9.2",
"babel-preset-react-native": "3.0.2",
"babel-preset-stage-0": "6.24.1",
"babel-register": "6.24.1",
"babel-register": "6.26.0",
"chai": "3.5.0",
"chai-enzyme": "0.6.1",
"chai-fetch-mock": "^1.0.0",
"chai-fetch-mock": "1.0.0",
"deep-freeze": "0.0.1",
"enzyme": "2.8.2",
"eslint": "3.19.0",
"eslint": "4.6.1",
"eslint-plugin-mocha": "4.9.0",
"eslint-plugin-react": "7.0.1",
"eslint-plugin-react": "7.3.0",
"fetch-mock": "5.10.0",
"form-data": "2.1.4",
"form-data": "2.3.1",
"jsdom": "10.1.0",
"jsdom-global": "3.0.2",
"mocha": "3.4.1",
"mocha-react-native": "0.5.0",
"nyc": "^10.3.2",
"mockery": "2.1.0",
"nyc": "10.3.2",
"react-addons-test-utils": "15.5.1",
"react-dom": "15.5.4",
"react-native-mock": "0.3.1",
"react-native-svg-mock": "1.0.2",
"react-test-renderer": "15.5.4",
"remote-redux-devtools": "0.5.10",
"remote-redux-devtools-on-debugger": "0.7.1"
"react-test-renderer": "16.0.0-alpha.12",
"remote-redux-devtools": "0.5.12",
"remote-redux-devtools-on-debugger": "0.8.2"
},
"scripts": {
"check": "node_modules/.bin/eslint --ext \".js\" --ignore-pattern node_modules --quiet .",

View file

@ -1,74 +0,0 @@
// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import React from 'react';
import {shallow} from 'enzyme';
import assert from 'assert';
import About from 'app/screens/about/about';
import Themes from 'assets/themes.json';
describe('AboutScreen', () => {
const props = {
config: {},
license: {},
theme: Themes.default
};
it('renders', () => {
const wrapper = shallow(<About {...props}/>);
assert.equal(wrapper.length, 1);
});
it('renders enterprise', () => {
const otherProps = {
...props,
config: {
BuildEnterpriseReady: 'true'
},
license: {
IsLicensed: 'true'
}
};
const wrapper = shallow(<About {...otherProps}/>);
assert.equal(wrapper.length, 1);
});
it('renders if config.BuildNumber !== config.Version', () => {
const otherProps = {
...props,
config: {
BuildNumber: 1,
Version: 2
}
};
const wrapper = shallow(<About {...otherProps}/>);
assert.equal(wrapper.length, 1);
});
it('opens about team url', () => {
const wrapper = shallow(<About {...props}/>);
const aboutLink = wrapper.find('TouchableOpacity');
aboutLink.simulate('press');
});
it('opens learn more url', () => {
const otherProps = {
...props,
config: {
BuildEnterpriseReady: 'true'
}
};
const wrapper = shallow(<About {...otherProps}/>);
const learnMore = wrapper.find('TouchableOpacity');
learnMore.simulate('press');
});
});

View file

@ -1,9 +1,5 @@
--require test/setup.js
--require test/mocks.js
--compilers js:babel-core/register
--compilers js:mocha-react-native/init
--require react-native-mock/mock.js
--require react-native-svg-mock/mock
--require babel-polyfill
--require jsdom-global/register
--recursive

View file

@ -9,39 +9,29 @@
import fs from 'fs';
import path from 'path';
import register from 'babel-core/register';
import chai from 'chai';
import chaiEnzyme from 'chai-enzyme';
import ReactNative from 'react-native-mock';
import {Sentry} from 'react-native-sentry';
import mockery from 'mockery';
const m = require('module');
const originalLoader = m._load;
const NativeModules = ReactNative.NativeModules;
const Platform = ReactNative.Platform;
NativeModules.RNCookieManagerIOS = {};
NativeModules.RNCookieManagerAndroid = {};
Platform.__setOS('ios');
// Image file ignore setup from:
// http://valuemotive.com/2016/08/01/unit-testing-react-native-components-with-mocha-and-enzyme/
m._load = function hookedLoader(request, parent, isMain) {
if (request.match(/.jpeg|.jpg|.png$/)) {
return {uri: request}
mockery.enable({
warnOnReplace: false,
warnOnUnregistered: false
});
mockery.registerMock('react-native', {
NativeModules: {}
});
mockery.registerMock('react-native-device-info', {
getDeviceLocale() {
return 'en';
}
return originalLoader(request, parent, isMain);
};
});
mockery.registerMock('react-native-sentry', {
Sentry: {
captureBreadcrumb() {}
}
});
// Ignore all node_modules except these
const modulesToCompile = [
'react-native',
'react-native-mock',
'react-native-svg-mock/mock',
'react-native-vector-icons',
'react-native-svg'
'react-native'
].map((moduleName) => new RegExp(`/node_modules/${moduleName}`));
const rcPath = path.join(__dirname, '..', '.babelrc');
@ -58,8 +48,3 @@ config.ignore = function(filename) {
};
register(config);
chai.use(chaiEnzyme());
// Initialize Sentry so that it doesn't complain when the middleware tries to create breadcrumbs
Sentry.config('');

2572
yarn.lock

File diff suppressed because it is too large Load diff