[NEW] Tablet support (#1300)

This commit is contained in:
Djorkaeff Alexandre 2019-11-25 17:01:17 -03:00 committed by Diego Mello
parent 4ace446334
commit a0dc2bad4a
101 changed files with 9847 additions and 8340 deletions

View File

@ -1,5 +1,6 @@
export default {
getModel: () => '',
getReadableVersion: () => '',
getBundleId: () => ''
getBundleId: () => '',
isTablet: () => false
};

View File

@ -9953,7 +9953,6 @@ exports[`Storyshots Message list 1`] = `
"borderColor": "#e1e5e8",
"borderRadius": 4,
"borderWidth": 1,
"maxWidth": 400,
"minHeight": 200,
"width": "100%",
},
@ -10211,7 +10210,6 @@ exports[`Storyshots Message list 1`] = `
"borderColor": "#e1e5e8",
"borderRadius": 4,
"borderWidth": 1,
"maxWidth": 400,
"minHeight": 200,
"width": "100%",
},
@ -11009,17 +11007,20 @@ exports[`Storyshots Message list 1`] = `
<View />
<View
style={
Object {
"alignItems": "center",
"backgroundColor": "#f3f4f5",
"borderColor": "#e1e5e8",
"borderRadius": 4,
"borderWidth": 1,
"flex": 1,
"flexDirection": "row",
"height": 56,
"marginBottom": 6,
}
Array [
Object {
"alignItems": "center",
"backgroundColor": "#f3f4f5",
"borderColor": "#e1e5e8",
"borderRadius": 4,
"borderWidth": 1,
"flex": 1,
"flexDirection": "row",
"height": 56,
"marginBottom": 6,
},
undefined,
]
}
>
View
@ -11334,17 +11335,20 @@ exports[`Storyshots Message list 1`] = `
<View />
<View
style={
Object {
"alignItems": "center",
"backgroundColor": "#f3f4f5",
"borderColor": "#e1e5e8",
"borderRadius": 4,
"borderWidth": 1,
"flex": 1,
"flexDirection": "row",
"height": 56,
"marginBottom": 6,
}
Array [
Object {
"alignItems": "center",
"backgroundColor": "#f3f4f5",
"borderColor": "#e1e5e8",
"borderRadius": 4,
"borderWidth": 1,
"flex": 1,
"flexDirection": "row",
"height": 56,
"marginBottom": 6,
},
undefined,
]
}
>
View
@ -11540,17 +11544,20 @@ exports[`Storyshots Message list 1`] = `
<View />
<View
style={
Object {
"alignItems": "center",
"backgroundColor": "#f3f4f5",
"borderColor": "#e1e5e8",
"borderRadius": 4,
"borderWidth": 1,
"flex": 1,
"flexDirection": "row",
"height": 56,
"marginBottom": 6,
}
Array [
Object {
"alignItems": "center",
"backgroundColor": "#f3f4f5",
"borderColor": "#e1e5e8",
"borderRadius": 4,
"borderWidth": 1,
"flex": 1,
"flexDirection": "row",
"height": 56,
"marginBottom": 6,
},
undefined,
]
}
>
View
@ -11718,17 +11725,20 @@ exports[`Storyshots Message list 1`] = `
<View />
<View
style={
Object {
"alignItems": "center",
"backgroundColor": "#f3f4f5",
"borderColor": "#e1e5e8",
"borderRadius": 4,
"borderWidth": 1,
"flex": 1,
"flexDirection": "row",
"height": 56,
"marginBottom": 6,
}
Array [
Object {
"alignItems": "center",
"backgroundColor": "#f3f4f5",
"borderColor": "#e1e5e8",
"borderRadius": 4,
"borderWidth": 1,
"flex": 1,
"flexDirection": "row",
"height": 56,
"marginBottom": 6,
},
undefined,
]
}
>
View
@ -12130,7 +12140,7 @@ exports[`Storyshots Message list 1`] = `
style={
Object {
"alignItems": "center",
"alignSelf": "flex-end",
"alignSelf": "flex-start",
"backgroundColor": "#f3f4f5",
"borderColor": "#e1e5e8",
"borderRadius": 4,
@ -12493,7 +12503,7 @@ exports[`Storyshots Message list 1`] = `
style={
Object {
"alignItems": "center",
"alignSelf": "flex-end",
"alignSelf": "flex-start",
"backgroundColor": "#f3f4f5",
"borderColor": "#e1e5e8",
"borderRadius": 4,
@ -19491,7 +19501,7 @@ exports[`Storyshots Message list 1`] = `
style={
Object {
"alignItems": "center",
"alignSelf": "flex-end",
"alignSelf": "flex-start",
"backgroundColor": "#f3f4f5",
"borderColor": "#e1e5e8",
"borderRadius": 4,
@ -20028,7 +20038,7 @@ exports[`Storyshots Message list 1`] = `
style={
Object {
"alignItems": "center",
"alignSelf": "flex-end",
"alignSelf": "flex-start",
"backgroundColor": "#f3f4f5",
"borderColor": "#e1e5e8",
"borderRadius": 4,
@ -20222,7 +20232,7 @@ exports[`Storyshots Message list 1`] = `
style={
Object {
"alignItems": "center",
"alignSelf": "flex-end",
"alignSelf": "flex-start",
"backgroundColor": "#f3f4f5",
"borderColor": "#e1e5e8",
"borderRadius": 4,

View File

@ -1,6 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:orientation="vertical"
android:background="@color/splashBackground"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/launch_screen" android:scaleType="centerCrop" />
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/launch_screen"
android:scaleType="fitCenter"
/>
</RelativeLayout>

187
app/commands.js Normal file
View File

@ -0,0 +1,187 @@
/* eslint-disable no-bitwise */
import { constants } from 'react-native-keycommands';
import I18n from './i18n';
const KEY_TYPING = '\t';
const KEY_PREFERENCES = 'p';
const KEY_SEARCH = 'f';
const KEY_PREVIOUS_ROOM = '[';
const KEY_NEXT_ROOM = ']';
const KEY_NEW_ROOM = __DEV__ ? 'e' : 'n';
const KEY_ROOM_ACTIONS = __DEV__ ? 'b' : 'i';
const KEY_UPLOAD = 'u';
const KEY_REPLY = ';';
const KEY_SERVER_SELECTION = __DEV__ ? 'o' : '`';
const KEY_ADD_SERVER = __DEV__ ? 'l' : 'n';
const KEY_SEND_MESSAGE = '\r';
const KEY_SELECT = '123456789';
export const defaultCommands = [
{
// Focus messageBox
input: KEY_TYPING,
modifierFlags: 0,
discoverabilityTitle: I18n.t('Type_message')
},
{
// Send message on textInput to current room
input: KEY_SEND_MESSAGE,
modifierFlags: 0,
discoverabilityTitle: I18n.t('Send')
}
];
export const keyCommands = [
{
// Open Preferences Modal
input: KEY_PREFERENCES,
modifierFlags: constants.keyModifierCommand,
discoverabilityTitle: I18n.t('Preferences')
},
{
// Focus Room Search
input: KEY_SEARCH,
modifierFlags: constants.keyModifierCommand | constants.keyModifierAlternate,
discoverabilityTitle: I18n.t('Room_search')
},
{
// Select a room by order using 1-9
input: '1...9',
modifierFlags: constants.keyModifierCommand,
discoverabilityTitle: I18n.t('Room_selection')
},
{
// Change room to next on Rooms List
input: KEY_NEXT_ROOM,
modifierFlags: constants.keyModifierCommand,
discoverabilityTitle: I18n.t('Next_room')
},
{
// Change room to previous on Rooms List
input: KEY_PREVIOUS_ROOM,
modifierFlags: constants.keyModifierCommand,
discoverabilityTitle: I18n.t('Previous_room')
},
{
// Open New Room Modal
input: KEY_NEW_ROOM,
modifierFlags: constants.keyModifierCommand,
discoverabilityTitle: I18n.t('New_room')
},
{
// Open Room Actions
input: KEY_ROOM_ACTIONS,
modifierFlags: constants.keyModifierCommand,
discoverabilityTitle: I18n.t('Room_actions')
},
{
// Upload a file to room
input: KEY_UPLOAD,
modifierFlags: constants.keyModifierCommand,
discoverabilityTitle: I18n.t('Upload_room')
},
{
// Search Messages on current room
input: KEY_SEARCH,
modifierFlags: constants.keyModifierCommand,
discoverabilityTitle: I18n.t('Search_messages')
},
{
// Scroll messages on current room
input: '↑ ↓',
modifierFlags: constants.keyModifierAlternate,
discoverabilityTitle: I18n.t('Scroll_messages')
},
{
// Scroll up messages on current room
input: constants.keyInputUpArrow,
modifierFlags: constants.keyModifierAlternate
},
{
// Scroll down messages on current room
input: constants.keyInputDownArrow,
modifierFlags: constants.keyModifierAlternate
},
{
// Reply latest message with Quote
input: KEY_REPLY,
modifierFlags: constants.keyModifierCommand,
discoverabilityTitle: I18n.t('Reply_latest')
},
{
// Open server dropdown
input: KEY_SERVER_SELECTION,
modifierFlags: constants.keyModifierCommand | constants.keyModifierAlternate,
discoverabilityTitle: I18n.t('Server_selection')
},
{
// Select a server by order using 1-9
input: '1...9',
modifierFlags: constants.keyModifierCommand | constants.keyModifierAlternate,
discoverabilityTitle: I18n.t('Server_selection_numbers')
},
{
// Navigate to add new server
input: KEY_ADD_SERVER,
modifierFlags: constants.keyModifierCommand | constants.keyModifierAlternate,
discoverabilityTitle: I18n.t('Add_server')
},
// Refers to select rooms on list
...([1, 2, 3, 4, 5, 6, 7, 8, 9].map(value => ({
input: `${ value }`,
modifierFlags: constants.keyModifierCommand
}))),
// Refers to select servers on list
...([1, 2, 3, 4, 5, 6, 7, 8, 9].map(value => ({
input: `${ value }`,
modifierFlags: constants.keyModifierCommand | constants.keyModifierAlternate
})))
];
export const KEY_COMMAND = 'KEY_COMMAND';
export const commandHandle = (event, key, flags = []) => {
const { input, modifierFlags } = event;
let _flags = 0;
if (flags.includes('command') && flags.includes('alternate')) {
_flags = constants.keyModifierCommand | constants.keyModifierAlternate;
} else if (flags.includes('command')) {
_flags = constants.keyModifierCommand;
} else if (flags.includes('alternate')) {
_flags = constants.keyModifierAlternate;
}
return key.includes(input) && modifierFlags === _flags;
};
export const handleCommandTyping = event => commandHandle(event, KEY_TYPING);
export const handleCommandSubmit = event => commandHandle(event, KEY_SEND_MESSAGE);
export const handleCommandShowUpload = event => commandHandle(event, KEY_UPLOAD, ['command']);
export const handleCommandScroll = event => commandHandle(event, [constants.keyInputUpArrow, constants.keyInputDownArrow], ['alternate']);
export const handleCommandRoomActions = event => commandHandle(event, KEY_ROOM_ACTIONS, ['command']);
export const handleCommandSearchMessages = event => commandHandle(event, KEY_SEARCH, ['command']);
export const handleCommandReplyLatest = event => commandHandle(event, KEY_REPLY, ['command']);
export const handleCommandSelectServer = event => commandHandle(event, KEY_SELECT, ['command', 'alternate']);
export const handleCommandShowPreferences = event => commandHandle(event, KEY_PREFERENCES, ['command']);
export const handleCommandSearching = event => commandHandle(event, KEY_SEARCH, ['command', 'alternate']);
export const handleCommandSelectRoom = event => commandHandle(event, KEY_SELECT, ['command']);
export const handleCommandPreviousRoom = event => commandHandle(event, KEY_PREVIOUS_ROOM, ['command']);
export const handleCommandNextRoom = event => commandHandle(event, KEY_NEXT_ROOM, ['command']);
export const handleCommandShowNewMessage = event => commandHandle(event, KEY_NEW_ROOM, ['command']);
export const handleCommandAddNewServer = event => commandHandle(event, KEY_ADD_SERVER, ['command', 'alternate']);
export const handleCommandOpenServerDropdown = event => commandHandle(event, KEY_SERVER_SELECTION, ['command', 'alternate']);

4
app/constants/tablet.js Normal file
View File

@ -0,0 +1,4 @@
export const MAX_SIDEBAR_WIDTH = 321;
export const MAX_CONTENT_WIDTH = '90%';
export const MAX_SCREEN_CONTENT_WIDTH = '45%';
export const MIN_WIDTH_SPLIT_LAYOUT = 700;

View File

@ -2,13 +2,14 @@ import React from 'react';
import PropTypes from 'prop-types';
import { View } from 'react-native';
import FastImage from 'react-native-fast-image';
import Touch from '../utils/touch';
const formatUrl = (url, baseUrl, uriSize, avatarAuthURLFragment) => (
`${ baseUrl }${ url }?format=png&width=${ uriSize }&height=${ uriSize }${ avatarAuthURLFragment }`
);
const Avatar = React.memo(({
text, size, baseUrl, borderRadius, style, avatar, type, children, userId, token
text, size, baseUrl, borderRadius, style, avatar, type, children, userId, token, onPress
}) => {
const avatarStyle = {
width: size,
@ -39,7 +40,7 @@ const Avatar = React.memo(({
}
const image = (
let image = (
<FastImage
style={avatarStyle}
source={{
@ -49,6 +50,14 @@ const Avatar = React.memo(({
/>
);
if (onPress) {
image = (
<Touch onPress={onPress}>
{image}
</Touch>
);
}
return (
<View style={[avatarStyle, style]}>
{image}
@ -67,7 +76,8 @@ Avatar.propTypes = {
type: PropTypes.string,
children: PropTypes.object,
userId: PropTypes.string,
token: PropTypes.string
token: PropTypes.string,
onPress: PropTypes.func
};
Avatar.defaultProps = {

View File

@ -1,20 +1,18 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Text, TouchableOpacity } from 'react-native';
import { Text, TouchableOpacity, FlatList } from 'react-native';
import { shortnameToUnicode } from 'emoji-toolkit';
import { responsive } from 'react-native-responsive-ui';
import { OptimizedFlatList } from 'react-native-optimized-flatlist';
import styles from './styles';
import CustomEmoji from './CustomEmoji';
import scrollPersistTaps from '../../utils/scrollPersistTaps';
import { isIOS } from '../../utils/deviceInfo';
const EMOJIS_PER_ROW = isIOS ? 8 : 9;
const EMOJI_SIZE = 50;
const renderEmoji = (emoji, size, baseUrl) => {
if (emoji.isCustom) {
return <CustomEmoji style={[styles.customCategoryEmoji, { height: size - 8, width: size - 8 }]} emoji={emoji} baseUrl={baseUrl} />;
if (emoji && emoji.isCustom) {
return <CustomEmoji style={[styles.customCategoryEmoji, { height: size - 16, width: size - 16 }]} emoji={emoji} baseUrl={baseUrl} />;
}
return (
<Text style={[styles.categoryEmoji, { height: size, width: size, fontSize: size - 14 }]}>
@ -33,44 +31,41 @@ class EmojiCategory extends React.Component {
width: PropTypes.number
}
constructor(props) {
super(props);
const { window, width, emojisPerRow } = this.props;
const { width: widthWidth, height: windowHeight } = window;
this.size = Math.min(width || widthWidth, windowHeight) / (emojisPerRow || EMOJIS_PER_ROW);
this.emojis = props.emojis;
}
shouldComponentUpdate() {
return false;
}
renderItem(emoji, size) {
renderItem(emoji) {
const { baseUrl, onEmojiSelected } = this.props;
return (
<TouchableOpacity
activeOpacity={0.7}
key={emoji.isCustom ? emoji.content : emoji}
key={emoji && emoji.isCustom ? emoji.content : emoji}
onPress={() => onEmojiSelected(emoji)}
testID={`reaction-picker-${ emoji.isCustom ? emoji.content : emoji }`}
testID={`reaction-picker-${ emoji && emoji.isCustom ? emoji.content : emoji }`}
>
{renderEmoji(emoji, size, baseUrl)}
{renderEmoji(emoji, EMOJI_SIZE, baseUrl)}
</TouchableOpacity>
);
}
render() {
const { emojis } = this.props;
const { emojis, width } = this.props;
if (!width) {
return null;
}
const numColumns = Math.trunc(width / EMOJI_SIZE);
const marginHorizontal = (width - (numColumns * EMOJI_SIZE)) / 2;
return (
<OptimizedFlatList
keyExtractor={item => (item.isCustom && item.content) || item}
<FlatList
contentContainerStyle={{ marginHorizontal }}
// rerender FlatList in case of width changes
key={`emoji-category-${ width }`}
keyExtractor={item => (item && item.isCustom && item.content) || item}
data={emojis}
renderItem={({ item }) => this.renderItem(item, this.size)}
numColumns={EMOJIS_PER_ROW}
extraData={this.props}
renderItem={({ item }) => this.renderItem(item)}
numColumns={numColumns}
initialNumToRender={45}
getItemLayout={(data, index) => ({ length: this.size, offset: this.size * index, index })}
removeClippedSubviews
{...scrollPersistTaps}
/>

View File

@ -1,6 +1,6 @@
import React, { Component } from 'react';
import { View } from 'react-native';
import PropTypes from 'prop-types';
import { ScrollView } from 'react-native';
import ScrollableTabView from 'react-native-scrollable-tab-view';
import { shortnameToUnicode } from 'emoji-toolkit';
import equal from 'deep-equal';
@ -27,9 +27,7 @@ class EmojiPicker extends Component {
baseUrl: PropTypes.string.isRequired,
customEmojis: PropTypes.object,
onEmojiSelected: PropTypes.func,
tabEmojiStyle: PropTypes.object,
emojisPerRow: PropTypes.number,
width: PropTypes.number
tabEmojiStyle: PropTypes.object
};
constructor(props) {
@ -44,7 +42,8 @@ class EmojiPicker extends Component {
this.state = {
frequentlyUsed: [],
customEmojis,
show: false
show: false,
width: null
};
}
@ -54,12 +53,11 @@ class EmojiPicker extends Component {
}
shouldComponentUpdate(nextProps, nextState) {
const { frequentlyUsed, show } = this.state;
const { width } = this.props;
const { frequentlyUsed, show, width } = this.state;
if (nextState.show !== show) {
return true;
}
if (nextProps.width !== width) {
if (nextState.width !== width) {
return true;
}
if (!equal(nextState.frequentlyUsed, frequentlyUsed)) {
@ -126,11 +124,11 @@ class EmojiPicker extends Component {
this.setState({ frequentlyUsed });
}
renderCategory(category, i) {
const { frequentlyUsed, customEmojis } = this.state;
const {
emojisPerRow, width, baseUrl
} = this.props;
onLayout = ({ nativeEvent: { layout: { width } } }) => this.setState({ width });
renderCategory(category, i, label) {
const { frequentlyUsed, customEmojis, width } = this.state;
const { baseUrl } = this.props;
let emojis = [];
if (i === 0) {
@ -145,9 +143,9 @@ class EmojiPicker extends Component {
emojis={emojis}
onEmojiSelected={emoji => this.onEmojiSelected(emoji)}
style={styles.categoryContainer}
size={emojisPerRow}
width={width}
baseUrl={baseUrl}
tabLabel={label}
/>
);
}
@ -160,26 +158,21 @@ class EmojiPicker extends Component {
return null;
}
return (
<ScrollableTabView
renderTabBar={() => <TabBar tabEmojiStyle={tabEmojiStyle} />}
contentProps={scrollProps}
style={styles.background}
>
{
categories.tabs.map((tab, i) => (
(i === 0 && frequentlyUsed.length === 0) ? null // when no frequentlyUsed don't show the tab
: (
<ScrollView
key={tab.category}
tabLabel={tab.tabLabel}
style={styles.background}
{...scrollProps}
>
{this.renderCategory(tab.category, i)}
</ScrollView>
)))
}
</ScrollableTabView>
<View onLayout={this.onLayout} style={{ flex: 1 }}>
<ScrollableTabView
renderTabBar={() => <TabBar tabEmojiStyle={tabEmojiStyle} />}
contentProps={scrollProps}
style={styles.background}
>
{
categories.tabs.map((tab, i) => (
(i === 0 && frequentlyUsed.length === 0) ? null // when no frequentlyUsed don't show the tab
: (
this.renderCategory(tab.category, i, tab.tabLabel)
)))
}
</ScrollableTabView>
</View>
);
}
}

View File

@ -56,6 +56,6 @@ export default StyleSheet.create({
textAlign: 'center'
},
customCategoryEmoji: {
margin: 4
margin: 8
}
});

View File

@ -35,11 +35,11 @@ const styles = StyleSheet.create({
});
const Content = React.memo(({
title, subtitle, disabled, testID, right
title, subtitle, disabled, testID, right, color
}) => (
<View style={[styles.container, disabled && styles.disabled]} testID={testID}>
<View style={styles.textContainer}>
<Text style={styles.title}>{title}</Text>
<Text style={[styles.title, color && { color }]}>{title}</Text>
{subtitle
? <Text style={styles.subtitle}>{subtitle}</Text>
: null
@ -78,6 +78,7 @@ Content.propTypes = {
subtitle: PropTypes.string,
right: PropTypes.func,
disabled: PropTypes.bool,
color: PropTypes.string,
testID: PropTypes.string
};

View File

@ -20,7 +20,7 @@ export default class EmojiKeyboard extends React.PureComponent {
render() {
return (
<View style={styles.emojiKeyboardContainer} testID='messagebox-keyboard-emoji'>
<EmojiPicker onEmojiSelected={emoji => this.onEmojiSelected(emoji)} baseUrl={this.baseUrl} />
<EmojiPicker onEmojiSelected={this.onEmojiSelected} baseUrl={this.baseUrl} />
</View>
);
}

View File

@ -11,17 +11,20 @@ import TextInput from '../TextInput';
import Button from '../Button';
import I18n from '../../i18n';
import sharedStyles from '../../views/Styles';
import { isIOS } from '../../utils/deviceInfo';
import { isIOS, isTablet } from '../../utils/deviceInfo';
import {
COLOR_PRIMARY, COLOR_BACKGROUND_CONTAINER, COLOR_WHITE
} from '../../constants/colors';
import { CustomIcon } from '../../lib/Icons';
import { withSplit } from '../../split';
const cancelButtonColor = COLOR_BACKGROUND_CONTAINER;
const styles = StyleSheet.create({
modal: {
alignItems: 'center'
width: '100%',
alignItems: 'center',
margin: 0
},
titleContainer: {
flexDirection: 'row',
@ -48,6 +51,9 @@ const styles = StyleSheet.create({
marginBottom: 16,
resizeMode: 'contain'
},
bigPreview: {
height: 250
},
buttonContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
@ -91,7 +97,8 @@ class UploadModal extends Component {
file: PropTypes.object,
close: PropTypes.func,
submit: PropTypes.func,
window: PropTypes.object
window: PropTypes.object,
split: PropTypes.bool
}
state = {
@ -113,11 +120,14 @@ class UploadModal extends Component {
shouldComponentUpdate(nextProps, nextState) {
const { name, description, file } = this.state;
const { window, isVisible } = this.props;
const { window, isVisible, split } = this.props;
if (nextState.name !== name) {
return true;
}
if (nextProps.split !== split) {
return true;
}
if (nextState.description !== description) {
return true;
}
@ -184,9 +194,9 @@ class UploadModal extends Component {
}
renderPreview() {
const { file } = this.props;
const { file, split } = this.props;
if (file.mime && file.mime.match(/image/)) {
return (<Image source={{ isStatic: true, uri: file.path }} style={styles.image} />);
return (<Image source={{ isStatic: true, uri: file.path }} style={[styles.image, split && styles.bigPreview]} />);
}
if (file.mime && file.mime.match(/video/)) {
return (
@ -200,7 +210,7 @@ class UploadModal extends Component {
render() {
const {
window: { width }, isVisible, close
window: { width }, isVisible, close, split
} = this.props;
const { name, description } = this.state;
return (
@ -215,7 +225,7 @@ class UploadModal extends Component {
hideModalContentWhileAnimating
avoidKeyboard
>
<View style={[styles.container, { width: width - 32 }]}>
<View style={[styles.container, { width: (isTablet ? '80%' : width - 32) }, split && sharedStyles.modal]}>
<View style={styles.titleContainer}>
<Text style={styles.title}>{I18n.t('Upload_file_question_mark')}</Text>
</View>
@ -240,4 +250,4 @@ class UploadModal extends Component {
}
}
export default responsive(UploadModal);
export default responsive(withSplit(UploadModal));

View File

@ -1,7 +1,7 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import {
View, TextInput, Alert
View, TextInput, Alert, Keyboard
} from 'react-native';
import { connect } from 'react-redux';
import { KeyboardAccessoryView } from 'react-native-keyboard-input';
@ -25,8 +25,15 @@ import debounce from '../../utils/debounce';
import { COLOR_TEXT_DESCRIPTION } from '../../constants/colors';
import LeftButtons from './LeftButtons';
import RightButtons from './RightButtons';
import { isAndroid } from '../../utils/deviceInfo';
import { isAndroid, isTablet } from '../../utils/deviceInfo';
import { canUploadFile } from '../../utils/media';
import EventEmiter from '../../utils/events';
import {
KEY_COMMAND,
handleCommandTyping,
handleCommandSubmit,
handleCommandShowUpload
} from '../../commands';
import Mentions from './Mentions';
import MessageboxContext from './Context';
import {
@ -98,8 +105,8 @@ class MessageBox extends Component {
commandPreview: [],
showCommandPreview: false
};
this.onEmojiSelected = this.onEmojiSelected.bind(this);
this.text = '';
this.focused = false;
this.fileOptions = [
I18n.t('Cancel'),
I18n.t('Take_a_photo'),
@ -162,6 +169,10 @@ class MessageBox extends Component {
if (isAndroid) {
require('./EmojiKeyboard');
}
if (isTablet) {
EventEmiter.addEventListener(KEY_COMMAND, this.handleCommands);
}
}
componentWillReceiveProps(nextProps) {
@ -239,12 +250,16 @@ class MessageBox extends Component {
if (this.getSlashCommands && this.getSlashCommands.stop) {
this.getSlashCommands.stop();
}
if (isTablet) {
EventEmiter.removeListener(KEY_COMMAND, this.handleCommands);
}
}
onChangeText = (text) => {
const isTextEmpty = text.length === 0;
this.setShowSend(!isTextEmpty);
this.debouncedOnChangeText(text);
this.setInput(text);
}
// eslint-disable-next-line react/sort-comp
@ -253,7 +268,6 @@ class MessageBox extends Component {
const isTextEmpty = text.length === 0;
// this.setShowSend(!isTextEmpty);
this.handleTyping(!isTextEmpty);
this.setInput(text);
// matches if their is text that stats with '/' and group the command and params so we can use it "/command params"
const slashCommand = text.match(/^\/([a-z0-9._-]+) (.+)/im);
if (slashCommand) {
@ -453,7 +467,10 @@ class MessageBox extends Component {
}
setShowSend = (showSend) => {
this.setState({ showSend });
const { showSend: prevShowSend } = this.state;
if (prevShowSend !== showSend) {
this.setState({ showSend });
}
}
clearInput = () => {
@ -624,6 +641,7 @@ class MessageBox extends Component {
const message = this.text;
this.clearInput();
this.debouncedOnChangeText.stop();
this.closeEmoji();
this.stopTrackingMention();
this.handleTyping(false);
@ -725,6 +743,21 @@ class MessageBox extends Component {
});
}
handleCommands = ({ event }) => {
if (handleCommandTyping(event)) {
if (this.focused) {
Keyboard.dismiss();
} else {
this.component.focus();
}
this.focused = !this.focused;
} else if (handleCommandSubmit(event)) {
this.submit();
} else if (handleCommandShowUpload(event)) {
this.showFileActions();
}
}
renderContent = () => {
const {
recording, showEmojiKeyboard, showSend, mentions, trackingType, commandPreview, showCommandPreview
@ -733,6 +766,12 @@ class MessageBox extends Component {
editing, message, replying, replyCancel, user, getCustomEmoji
} = this.props;
const isAndroidTablet = isTablet && isAndroid ? {
multiline: false,
onSubmitEditing: this.submit,
returnKeyType: 'send'
} : {};
if (recording) {
return <Recording onFinish={this.finishAudioMessage} />;
}
@ -773,6 +812,7 @@ class MessageBox extends Component {
multiline
placeholderTextColor={COLOR_TEXT_DESCRIPTION}
testID='messagebox-input'
{...isAndroidTablet}
/>
<RightButtons
showSend={showSend}

View File

@ -56,12 +56,13 @@ const CancelButton = onCancelPress => (
);
const SearchBox = ({
onChangeText, onSubmitEditing, testID, hasCancel, onCancelPress, ...props
onChangeText, onSubmitEditing, testID, hasCancel, onCancelPress, inputRef, ...props
}) => (
<View style={styles.container}>
<View style={styles.searchBox}>
<CustomIcon name='magnifier' size={14} color='#8E8E93' />
<TextInput
ref={inputRef}
autoCapitalize='none'
autoCorrect={false}
blurOnSubmit
@ -85,6 +86,7 @@ SearchBox.propTypes = {
onSubmitEditing: PropTypes.func,
hasCancel: PropTypes.bool,
onCancelPress: PropTypes.func,
inputRef: PropTypes.func,
testID: PropTypes.string
};

View File

@ -14,6 +14,7 @@ import { CustomIcon } from '../../lib/Icons';
import sharedStyles from '../../views/Styles';
import { COLOR_BACKGROUND_CONTAINER, COLOR_BORDER, COLOR_PRIMARY } from '../../constants/colors';
import { isAndroid, isIOS } from '../../utils/deviceInfo';
import { withSplit } from '../../split';
const styles = StyleSheet.create({
audioContainer: {
@ -73,12 +74,13 @@ Button.propTypes = {
};
Button.displayName = 'MessageAudioButton';
export default class Audio extends React.Component {
class Audio extends React.Component {
static propTypes = {
file: PropTypes.object.isRequired,
baseUrl: PropTypes.string.isRequired,
user: PropTypes.object.isRequired,
useMarkdown: PropTypes.bool,
split: PropTypes.bool,
getCustomEmoji: PropTypes.func
}
@ -97,7 +99,7 @@ export default class Audio extends React.Component {
const {
currentTime, duration, paused, uri
} = this.state;
const { file } = this.props;
const { file, split } = this.props;
if (nextState.currentTime !== currentTime) {
return true;
}
@ -113,6 +115,9 @@ export default class Audio extends React.Component {
if (!equal(nextProps.file, file)) {
return true;
}
if (nextProps.split !== split) {
return true;
}
return false;
}
@ -153,7 +158,7 @@ export default class Audio extends React.Component {
uri, paused, currentTime, duration
} = this.state;
const {
user, baseUrl, file, getCustomEmoji, useMarkdown
user, baseUrl, file, getCustomEmoji, useMarkdown, split
} = this.props;
const { description } = file;
@ -163,7 +168,7 @@ export default class Audio extends React.Component {
return (
<>
<View style={styles.audioContainer}>
<View style={[styles.audioContainer, split && sharedStyles.tabletContent]}>
<Video
ref={this.setRef}
source={{ uri }}
@ -193,3 +198,5 @@ export default class Audio extends React.Component {
);
}
}
export default withSplit(Audio);

View File

@ -8,11 +8,13 @@ import Touchable from 'react-native-platform-touchable';
import Markdown from '../markdown';
import styles from './styles';
import { formatAttachmentUrl } from '../../lib/utils';
import { withSplit } from '../../split';
import sharedStyles from '../../views/Styles';
const Button = React.memo(({ children, onPress }) => (
const Button = React.memo(({ children, onPress, split }) => (
<Touchable
onPress={onPress}
style={styles.imageContainer}
style={[styles.imageContainer, split && sharedStyles.tabletContent]}
background={Touchable.Ripple('#fff')}
>
{children}
@ -28,7 +30,7 @@ const Image = React.memo(({ img }) => (
));
const ImageContainer = React.memo(({
file, baseUrl, user, useMarkdown, onOpenFileModal, getCustomEmoji
file, baseUrl, user, useMarkdown, onOpenFileModal, getCustomEmoji, split
}) => {
const img = formatAttachmentUrl(file.image_url, user.id, user.token, baseUrl);
if (!img) {
@ -39,7 +41,7 @@ const ImageContainer = React.memo(({
if (file.description) {
return (
<Button onPress={onPress}>
<Button split={split} onPress={onPress}>
<View>
<Image img={img} />
<Markdown msg={file.description} baseUrl={baseUrl} username={user.username} getCustomEmoji={getCustomEmoji} useMarkdown={useMarkdown} />
@ -49,11 +51,11 @@ const ImageContainer = React.memo(({
}
return (
<Button onPress={onPress}>
<Button split={split} onPress={onPress}>
<Image img={img} />
</Button>
);
}, (prevProps, nextProps) => equal(prevProps.file, nextProps.file));
}, (prevProps, nextProps) => equal(prevProps.file, nextProps.file) && prevProps.split === nextProps.split);
ImageContainer.propTypes = {
file: PropTypes.object,
@ -61,7 +63,8 @@ ImageContainer.propTypes = {
user: PropTypes.object,
useMarkdown: PropTypes.bool,
onOpenFileModal: PropTypes.func,
getCustomEmoji: PropTypes.func
getCustomEmoji: PropTypes.func,
split: PropTypes.bool
};
ImageContainer.displayName = 'MessageImageContainer';
@ -72,8 +75,9 @@ ImageContainer.displayName = 'MessageImage';
Button.propTypes = {
children: PropTypes.node,
onPress: PropTypes.func
onPress: PropTypes.func,
split: PropTypes.bool
};
ImageContainer.displayName = 'MessageButton';
export default ImageContainer;
export default withSplit(ImageContainer);

View File

@ -9,6 +9,7 @@ import Markdown from '../markdown';
import openLink from '../../utils/openLink';
import sharedStyles from '../../views/Styles';
import { COLOR_BACKGROUND_CONTAINER, COLOR_BORDER } from '../../constants/colors';
import { withSplit } from '../../split';
const styles = StyleSheet.create({
button: {
@ -16,7 +17,7 @@ const styles = StyleSheet.create({
flexDirection: 'row',
alignItems: 'center',
marginTop: 6,
alignSelf: 'flex-end',
alignSelf: 'flex-start',
backgroundColor: COLOR_BACKGROUND_CONTAINER,
borderColor: COLOR_BORDER,
borderWidth: 1,
@ -126,7 +127,7 @@ const Fields = React.memo(({ attachment }) => {
}, (prevProps, nextProps) => isEqual(prevProps.attachment.fields, nextProps.attachment.fields));
const Reply = React.memo(({
attachment, timeFormat, baseUrl, user, index, getCustomEmoji, useMarkdown
attachment, timeFormat, baseUrl, user, index, getCustomEmoji, useMarkdown, split
}) => {
if (!attachment) {
return null;
@ -146,7 +147,7 @@ const Reply = React.memo(({
return (
<Touchable
onPress={onPress}
style={[styles.button, index > 0 && styles.marginTop]}
style={[styles.button, index > 0 && styles.marginTop, split && sharedStyles.tabletContent]}
background={Touchable.Ripple('#fff')}
>
<View style={styles.attachmentContainer}>
@ -163,7 +164,7 @@ const Reply = React.memo(({
</View>
</Touchable>
);
}, (prevProps, nextProps) => isEqual(prevProps.attachment, nextProps.attachment));
}, (prevProps, nextProps) => isEqual(prevProps.attachment, nextProps.attachment) && prevProps.split === nextProps.split);
Reply.propTypes = {
attachment: PropTypes.object,
@ -172,7 +173,8 @@ Reply.propTypes = {
user: PropTypes.object,
index: PropTypes.number,
useMarkdown: PropTypes.bool,
getCustomEmoji: PropTypes.func
getCustomEmoji: PropTypes.func,
split: PropTypes.bool
};
Reply.displayName = 'MessageReply';
@ -196,4 +198,4 @@ Fields.propTypes = {
};
Fields.displayName = 'MessageReplyFields';
export default Reply;
export default withSplit(Reply);

View File

@ -10,6 +10,7 @@ import sharedStyles from '../../views/Styles';
import {
COLOR_BACKGROUND_CONTAINER, COLOR_BORDER, COLOR_PRIMARY
} from '../../constants/colors';
import { withSplit } from '../../split';
const styles = StyleSheet.create({
button: {
@ -75,7 +76,7 @@ const UrlContent = React.memo(({ title, description }) => (
});
const Url = React.memo(({
url, index, user, baseUrl
url, index, user, baseUrl, split
}) => {
if (!url) {
return null;
@ -86,7 +87,7 @@ const Url = React.memo(({
return (
<Touchable
onPress={onPress}
style={[styles.button, index > 0 && styles.marginTop, styles.container]}
style={[styles.button, index > 0 && styles.marginTop, styles.container, split && sharedStyles.tabletContent]}
background={Touchable.Ripple('#fff')}
>
<>
@ -95,17 +96,19 @@ const Url = React.memo(({
</>
</Touchable>
);
}, (oldProps, newProps) => isEqual(oldProps.url, newProps.url));
}, (oldProps, newProps) => isEqual(oldProps.url, newProps.url) && oldProps.split === newProps.split);
const Urls = React.memo(({ urls, user, baseUrl }) => {
const Urls = React.memo(({
urls, user, baseUrl, split
}) => {
if (!urls || urls.length === 0) {
return null;
}
return urls.map((url, index) => (
<Url url={url} key={url.url} index={index} user={user} baseUrl={baseUrl} />
<Url url={url} key={url.url} index={index} user={user} baseUrl={baseUrl} split={split} />
));
}, (oldProps, newProps) => isEqual(oldProps.urls, newProps.urls));
}, (oldProps, newProps) => isEqual(oldProps.urls, newProps.urls) && oldProps.split === newProps.split);
UrlImage.propTypes = {
image: PropTypes.string,
@ -124,15 +127,17 @@ Url.propTypes = {
url: PropTypes.object.isRequired,
index: PropTypes.number,
user: PropTypes.object,
baseUrl: PropTypes.string
baseUrl: PropTypes.string,
split: PropTypes.bool
};
Url.displayName = 'MessageUrl';
Urls.propTypes = {
urls: PropTypes.array,
user: PropTypes.object,
baseUrl: PropTypes.string
baseUrl: PropTypes.string,
split: PropTypes.bool
};
Urls.displayName = 'MessageUrls';
export default Urls;
export default withSplit(Urls);

View File

@ -6,9 +6,10 @@ import isEqual from 'deep-equal';
import Markdown from '../markdown';
import openLink from '../../utils/openLink';
import { isIOS } from '../../utils/deviceInfo';
import { isIOS, isTablet } from '../../utils/deviceInfo';
import { CustomIcon } from '../../lib/Icons';
import { formatAttachmentUrl } from '../../lib/utils';
import sharedStyles from '../../views/Styles';
const SUPPORTED_TYPES = ['video/quicktime', 'video/mp4', ...(isIOS ? [] : ['video/3gp', 'video/mkv'])];
const isTypeSupported = type => SUPPORTED_TYPES.indexOf(type) !== -1;
@ -51,7 +52,7 @@ const Video = React.memo(({
<>
<Touchable
onPress={onPress}
style={styles.button}
style={[styles.button, isTablet && sharedStyles.tabletContent]}
background={Touchable.Ripple('#fff')}
>
<CustomIcon

View File

@ -4,6 +4,7 @@ import sharedStyles from '../../views/Styles';
import {
COLOR_BORDER, COLOR_PRIMARY, COLOR_WHITE
} from '../../constants/colors';
import { isTablet } from '../../utils/deviceInfo';
export default StyleSheet.create({
root: {
@ -121,8 +122,8 @@ export default StyleSheet.create({
},
image: {
width: '100%',
maxWidth: 400,
minHeight: 200,
// maxWidth: 400,
minHeight: isTablet ? 300 : 200,
borderRadius: 4,
borderColor: COLOR_BORDER,
borderWidth: 1

View File

@ -279,6 +279,7 @@ export default {
pinned: 'pinned',
Pinned: 'Pinned',
Please_enter_your_password: 'Please enter your password',
Preferences: 'Preferences',
Preferences_saved: 'Preferences saved!',
Privacy_Policy: ' Privacy Policy',
Private_Channel: 'Private Channel',
@ -441,5 +442,19 @@ export default {
Version_no: 'Version: {{version}}',
You_will_not_be_able_to_recover_this_message: 'You will not be able to recover this message!',
Change_Language: 'Change Language',
Crash_report_disclaimer: 'We never track the content of your chats. The crash report only contains relevant information for us in order to identify problems and fix it.'
Crash_report_disclaimer: 'We never track the content of your chats. The crash report only contains relevant information for us in order to identify problems and fix it.',
Type_message: 'Type message',
Room_search: 'Rooms search',
Room_selection: 'Room selection 1...9',
Next_room: 'Next room',
Previous_room: 'Previous room',
New_room: 'New room',
Upload_room: 'Upload to room',
Search_messages: 'Search messages',
Scroll_messages: 'Scroll messages',
Reply_latest: 'Reply to latest',
Server_selection: 'Server selection',
Server_selection_numbers: 'Server selection 1...9',
Add_server: 'Add server',
New_line: 'New line'
};

View File

@ -257,6 +257,7 @@ export default {
pinned: 'fixada',
Pinned: 'Mensagens Fixadas',
Please_enter_your_password: 'Por favor, digite sua senha',
Preferences: 'Preferências',
Preferences_saved: 'Preferências salvas!',
Privacy_Policy: ' Política de Privacidade',
Private_Channel: 'Canal Privado',
@ -392,5 +393,20 @@ export default {
you: 'você',
You: 'Você',
You_need_to_access_at_least_one_RocketChat_server_to_share_something: 'Você precisa acessar ao menos um servidor Rocket.Chat para compartilhar.',
You_will_not_be_able_to_recover_this_message: 'Você não será capaz de recuperar essa mensagem!'
You_will_not_be_able_to_recover_this_message: 'Você não será capaz de recuperar essa mensagem!',
Crash_report_disclaimer: 'Nós não rastreamos o conteúdo das suas conversas. O relatório de erros apenas contém informações relevantes para identificarmos problemas e corrigí-los.',
Type_message: 'Digitar mensagem',
Room_search: 'Busca de sala',
Room_selection: 'Selecionar sala 1...9',
Next_room: 'Próxima sala',
Previous_room: 'Sala anterior',
New_room: 'Nova sala',
Upload_room: 'Enviar arquivo',
Search_messages: 'Buscar mensagens',
Scroll_messages: 'Rolar mensagens',
Reply_latest: 'Responder para última mensagem',
Server_selection: 'Seleção de servidor',
Server_selection_numbers: 'Selecionar servidor 1...9',
Add_server: 'Adicionar servidor',
New_line: 'Nova linha'
};

View File

@ -1,11 +1,14 @@
import React from 'react';
import { View, Linking, BackHandler } from 'react-native';
import { createAppContainer, createSwitchNavigator } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
import { createDrawerNavigator } from 'react-navigation-drawer';
import { Provider } from 'react-redux';
import { Linking } from 'react-native';
import PropTypes from 'prop-types';
import Modal from 'react-native-modal';
import KeyCommands, { KeyCommandsEmitter } from 'react-native-keycommands';
import EventEmitter from './utils/events';
import { appInit } from './actions';
import { deepLinkingOpen } from './actions/deepLinking';
import Navigation from './lib/Navigation';
@ -18,7 +21,14 @@ import { defaultHeader, onNavigationStateChange } from './utils/navigation';
import { loggerConfig, analytics } from './utils/log';
import Toast from './containers/Toast';
import RocketChat from './lib/rocketchat';
import { isIOS } from './utils/deviceInfo';
import { MIN_WIDTH_SPLIT_LAYOUT } from './constants/tablet';
import {
isTablet, isSplited, isIOS, setWidth
} from './utils/deviceInfo';
import { KEY_COMMAND } from './commands';
import Tablet, { initTabletNav } from './tablet';
import sharedStyles from './views/Styles';
import { SplitContext } from './split';
if (isIOS) {
const RNScreens = require('react-native-screens');
@ -84,14 +94,26 @@ const OutsideStackModal = createStackNavigator({
headerMode: 'none'
});
const RoomRoutes = {
RoomView: {
getScreen: () => require('./views/RoomView').default
},
ThreadMessagesView: {
getScreen: () => require('./views/ThreadMessagesView').default
},
MarkdownTableView: {
getScreen: () => require('./views/MarkdownTableView').default
},
ReadReceiptsView: {
getScreen: () => require('./views/ReadReceiptView').default
}
};
// Inside
const ChatsStack = createStackNavigator({
RoomsListView: {
getScreen: () => require('./views/RoomsListView').default
},
RoomView: {
getScreen: () => require('./views/RoomView').default
},
RoomActionsView: {
getScreen: () => require('./views/RoomActionsView').default
},
@ -110,34 +132,33 @@ const ChatsStack = createStackNavigator({
SelectedUsersView: {
getScreen: () => require('./views/SelectedUsersView').default
},
ThreadMessagesView: {
getScreen: () => require('./views/ThreadMessagesView').default
},
MessagesView: {
getScreen: () => require('./views/MessagesView').default
},
AutoTranslateView: {
getScreen: () => require('./views/AutoTranslateView').default
},
ReadReceiptsView: {
getScreen: () => require('./views/ReadReceiptView').default
},
DirectoryView: {
getScreen: () => require('./views/DirectoryView').default
},
TableView: {
getScreen: () => require('./views/TableView').default
},
NotificationPrefView: {
getScreen: () => require('./views/NotificationPreferencesView').default
}
},
...RoomRoutes
}, {
defaultNavigationOptions: defaultHeader
});
// Inside
const RoomStack = createStackNavigator({
...RoomRoutes
}, {
defaultNavigationOptions: defaultHeader
});
ChatsStack.navigationOptions = ({ navigation }) => {
let drawerLockMode = 'unlocked';
if (navigation.state.index > 0) {
if (navigation.state.index > 0 || isSplited()) {
drawerLockMode = 'locked-closed';
}
return {
@ -238,22 +259,188 @@ class CustomInsideStack extends React.Component {
static router = InsideStackModal.router;
static propTypes = {
navigation: PropTypes.object
navigation: PropTypes.object,
screenProps: PropTypes.object
}
render() {
const { navigation } = this.props;
const { navigation, screenProps } = this.props;
return (
<>
<InsideStackModal navigation={navigation} />
<NotificationBadge navigation={navigation} />
<InsideStackModal navigation={navigation} screenProps={screenProps} />
{ !isTablet ? <NotificationBadge navigation={navigation} /> : null }
{ !isTablet ? <Toast /> : null }
</>
);
}
}
class CustomRoomStack extends React.Component {
static router = RoomStack.router;
static propTypes = {
navigation: PropTypes.object,
screenProps: PropTypes.object
}
render() {
const { navigation, screenProps } = this.props;
return (
<>
<RoomStack navigation={navigation} screenProps={screenProps} />
<Toast />
</>
);
}
}
const App = createAppContainer(createSwitchNavigator(
const MessagesStack = createStackNavigator({
NewMessageView: {
getScreen: () => require('./views/NewMessageView').default
},
SelectedUsersViewCreateChannel: {
getScreen: () => require('./views/SelectedUsersView').default
},
CreateChannelView: {
getScreen: () => require('./views/CreateChannelView').default
}
}, {
defaultNavigationOptions: defaultHeader
});
const DirectoryStack = createStackNavigator({
DirectoryView: {
getScreen: () => require('./views/DirectoryView').default
}
}, {
defaultNavigationOptions: defaultHeader
});
const SidebarStack = createStackNavigator({
SettingsView: {
getScreen: () => require('./views/SettingsView').default
},
ProfileView: {
getScreen: () => require('./views/ProfileView').default
},
AdminPanelView: {
getScreen: () => require('./views/AdminPanelView').default
}
}, {
defaultNavigationOptions: defaultHeader
});
const RoomActionsStack = createStackNavigator({
RoomActionsView: {
getScreen: () => require('./views/RoomActionsView').default
},
RoomInfoView: {
getScreen: () => require('./views/RoomInfoView').default
},
RoomInfoEditView: {
getScreen: () => require('./views/RoomInfoEditView').default
},
RoomMembersView: {
getScreen: () => require('./views/RoomMembersView').default
},
SearchMessagesView: {
getScreen: () => require('./views/SearchMessagesView').default
},
SelectedUsersView: {
getScreen: () => require('./views/SelectedUsersView').default
},
MessagesView: {
getScreen: () => require('./views/MessagesView').default
},
AutoTranslateView: {
getScreen: () => require('./views/AutoTranslateView').default
},
ReadReceiptsView: {
getScreen: () => require('./views/ReadReceiptView').default
},
NotificationPrefView: {
getScreen: () => require('./views/NotificationPreferencesView').default
}
}, {
defaultNavigationOptions: defaultHeader
});
const ModalSwitch = createSwitchNavigator({
MessagesStack,
DirectoryStack,
SidebarStack,
RoomActionsStack,
SettingsStack,
AuthLoading: () => null
},
{
initialRouteName: 'AuthLoading'
});
class CustomModalStack extends React.Component {
static router = ModalSwitch.router;
static propTypes = {
navigation: PropTypes.object,
showModal: PropTypes.bool,
closeModal: PropTypes.func,
screenProps: PropTypes.object
}
componentDidMount() {
this.backHandler = BackHandler.addEventListener('hardwareBackPress', this.closeModal);
}
componentWillUnmount() {
this.backHandler.remove();
}
closeModal = () => {
const { closeModal, navigation } = this.props;
const { state } = navigation;
if (state && state.routes[state.index] && state.routes[state.index].index === 0) {
closeModal();
return true;
}
return false;
}
render() {
const {
navigation, showModal, closeModal, screenProps
} = this.props;
return (
<Modal
useNativeDriver
coverScreen={false}
isVisible={showModal}
onBackdropPress={closeModal}
hideModalContentWhileAnimating
avoidKeyboard
>
<View style={sharedStyles.modal}>
<ModalSwitch navigation={navigation} screenProps={screenProps} />
</View>
</Modal>
);
}
}
class CustomNotificationStack extends React.Component {
static router = InsideStackModal.router;
static propTypes = {
navigation: PropTypes.object
}
render() {
const { navigation } = this.props;
return <NotificationBadge navigation={navigation} />;
}
}
export const App = createAppContainer(createSwitchNavigator(
{
OutsideStack: OutsideStackModal,
InsideStack: CustomInsideStack,
@ -267,11 +454,25 @@ const App = createAppContainer(createSwitchNavigator(
}
));
export const RoomContainer = createAppContainer(CustomRoomStack);
export const ModalContainer = createAppContainer(CustomModalStack);
export const NotificationContainer = createAppContainer(CustomNotificationStack);
export default class Root extends React.Component {
constructor(props) {
super(props);
this.init();
this.initCrashReport();
this.state = {
split: false,
inside: false,
showModal: false
};
if (isTablet) {
this.initTablet();
}
}
componentDidMount() {
@ -285,8 +486,23 @@ export default class Root extends React.Component {
}, 5000);
}
// eslint-disable-next-line no-unused-vars
componentDidUpdate(_, prevState) {
if (isTablet) {
const { split, inside } = this.state;
if (inside && split !== prevState.split) {
// Reset app on split mode changes
Navigation.navigate('RoomsListView');
this.closeModal();
}
}
}
componentWillUnmount() {
clearTimeout(this.listenerTimeout);
if (this.onKeyCommands && this.onKeyCommands.remove) {
this.onKeyCommands.remove();
}
}
init = async() => {
@ -301,6 +517,15 @@ export default class Root extends React.Component {
}
}
initTablet = async() => {
initTabletNav(args => this.setState(args));
await KeyCommands.setKeyCommands([]);
this.onKeyCommands = KeyCommandsEmitter.addListener(
'onKeyCommand',
command => EventEmitter.emit(KEY_COMMAND, { event: command })
);
}
initCrashReport = () => {
RocketChat.getAllowCrashReport()
.then((allowCrashReport) => {
@ -312,15 +537,47 @@ export default class Root extends React.Component {
});
}
onLayout = ({ nativeEvent: { layout: { width } } }) => (isTablet ? this.setSplit(width) : null);
setSplit = (width) => {
this.setState({ split: width > MIN_WIDTH_SPLIT_LAYOUT });
setWidth(width);
}
closeModal = () => this.setState({ showModal: false });
render() {
const { split } = this.state;
let content = (
<App
ref={(navigatorRef) => {
Navigation.setTopLevelNavigator(navigatorRef);
}}
screenProps={{ split }}
onNavigationStateChange={onNavigationStateChange}
/>
);
if (isTablet) {
const { inside, showModal } = this.state;
content = (
<SplitContext.Provider value={{ split }}>
<Tablet
tablet={split}
inside={inside}
showModal={showModal}
closeModal={this.closeModal}
onLayout={this.onLayout}
>
{content}
</Tablet>
</SplitContext.Provider>
);
}
return (
<Provider store={store}>
<App
ref={(navigatorRef) => {
Navigation.setTopLevelNavigator(navigatorRef);
}}
onNavigationStateChange={onNavigationStateChange}
/>
{content}
</Provider>
);
}

View File

@ -0,0 +1,21 @@
import { NavigationActions } from 'react-navigation';
let _navigatorModal;
function setTopLevelNavigator(navigatorRef) {
_navigatorModal = navigatorRef;
}
function navigate(routeName, params) {
_navigatorModal.dispatch(
NavigationActions.navigate({
routeName,
params
})
);
}
export default {
navigate,
setTopLevelNavigator
};

View File

@ -8,7 +8,7 @@ import equal from 'deep-equal';
import { responsive } from 'react-native-responsive-ui';
import Touchable from 'react-native-platform-touchable';
import { isNotch, isIOS } from '../../utils/deviceInfo';
import { isNotch, isIOS, isTablet } from '../../utils/deviceInfo';
import { CustomIcon } from '../../lib/Icons';
import { COLOR_BACKGROUND_NOTIFICATION, COLOR_SEPARATOR, COLOR_TEXT } from '../../constants/colors';
import Avatar from '../../containers/Avatar';
@ -158,7 +158,7 @@ class NotificationBadge extends React.Component {
}
goToRoom = async() => {
const { notification: { payload }, navigation } = this.props;
const { notification: { payload }, navigation, baseUrl } = this.props;
const { rid, type, prid } = payload;
if (!rid) {
return;
@ -166,7 +166,7 @@ class NotificationBadge extends React.Component {
const name = type === 'd' ? payload.sender.username : payload.name;
await navigation.navigate('RoomsListView');
navigation.navigate('RoomView', {
rid, name, t: type, prid
rid, name, t: type, prid, baseUrl
});
this.hide();
}
@ -185,7 +185,7 @@ class NotificationBadge extends React.Component {
if (portrait) {
top = isNotch ? 45 : 20;
} else {
top = 0;
top = isTablet ? 20 : 0;
}
}

View File

@ -21,7 +21,7 @@ export const LeftActions = React.memo(({
});
return (
<View
style={styles.actionsContainer}
style={[styles.actionsContainer, styles.actionLeftContainer]}
pointerEvents='box-none'
>
<Animated.View

View File

@ -117,6 +117,9 @@ export default StyleSheet.create({
marginTop: 4,
...sharedStyles.textSemibold
},
actionLeftContainer: {
backgroundColor: COLOR_PRIMARY
},
actionLeftButtonContainer: {
position: 'absolute',
height: ROW_HEIGHT,

View File

@ -114,7 +114,10 @@ const handleLoginSuccess = function* handleLoginSuccess({ user }) {
yield put(serverFinishAdd());
yield put(appStart('inside'));
} else {
yield put(appStart('inside'));
const currentRoot = yield select(state => state.app.root);
if (currentRoot !== 'inside') {
yield put(appStart('inside'));
}
}
} catch (e) {
log(e);

View File

@ -7,24 +7,30 @@ import RocketChat from '../lib/rocketchat';
import database from '../lib/database';
import log from '../utils/log';
const goRoom = function goRoom({ rid, name, message }) {
const goRoom = function goRoom({
rid, name, fname, message
}) {
Navigation.navigate('RoomsListView');
Navigation.navigate('RoomView', {
rid, name, t: 'd', message
rid, name, fname, t: 'd', message
});
};
const handleReplyBroadcast = function* handleReplyBroadcast({ message }) {
try {
const db = database.active;
const { username } = message.u;
const { username, name } = message.u;
const subsCollection = db.collections.get('subscriptions');
const subscriptions = yield subsCollection.query(Q.where('name', username)).fetch();
if (subscriptions.length) {
yield goRoom({ rid: subscriptions[0].rid, name: username, message });
yield goRoom({
rid: subscriptions[0].rid, name: username, fname: name, message
});
} else {
const room = yield RocketChat.createDirectMessage(username);
yield goRoom({ rid: room.rid, name: username, message });
yield goRoom({
rid: room.rid, name: username, fname: name, message
});
}
} catch (e) {
log(e);

19
app/split.js Normal file
View File

@ -0,0 +1,19 @@
import React from 'react';
import hoistNonReactStatics from 'hoist-non-react-statics';
import { isTablet } from './utils/deviceInfo';
export const SplitContext = React.createContext(null);
export function withSplit(Component) {
if (isTablet) {
const SplitComponent = props => (
<SplitContext.Consumer>
{contexts => <Component {...props} {...contexts} />}
</SplitContext.Consumer>
);
hoistNonReactStatics(SplitComponent, Component);
return SplitComponent;
}
return Component;
}

199
app/tablet.js Normal file
View File

@ -0,0 +1,199 @@
import React from 'react';
import { View } from 'react-native';
import PropTypes from 'prop-types';
import { NavigationActions, StackActions } from 'react-navigation';
import KeyCommands from 'react-native-keycommands';
import Navigation from './lib/Navigation';
import { isSplited } from './utils/deviceInfo';
import {
App, RoomContainer, ModalContainer, NotificationContainer
} from './index';
import { MAX_SIDEBAR_WIDTH } from './constants/tablet';
import ModalNavigation from './lib/ModalNavigation';
import { keyCommands, defaultCommands } from './commands';
import sharedStyles from './views/Styles';
let modalRef;
let roomRef;
let notificationRef;
export const initTabletNav = (setState) => {
let inCall = false;
const defaultApp = App.router.getStateForAction;
const defaultModal = ModalContainer.router.getStateForAction;
const defaultRoom = RoomContainer.router.getStateForAction;
const defaultNotification = NotificationContainer.router.getStateForAction;
NotificationContainer.router.getStateForAction = (action, state) => {
if (action.type === NavigationActions.NAVIGATE && isSplited()) {
const { routeName, params } = action;
if (routeName === 'RoomView') {
const resetAction = StackActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName, params })]
});
roomRef.dispatch(resetAction);
}
}
return defaultNotification(action, state);
};
RoomContainer.router.getStateForAction = (action, state) => {
if (action.type === NavigationActions.NAVIGATE && isSplited()) {
const { routeName, params } = action;
if (routeName === 'RoomActionsView') {
modalRef.dispatch(NavigationActions.navigate({ routeName, params }));
setState({ showModal: true });
return null;
}
}
if (action.type === 'Navigation/RESET' && isSplited()) {
const { params } = action.actions[action.index];
const routes = state.routes[state.index] && state.routes[state.index].params;
if (params && params.rid && routes && routes.rid && params.rid === routes.rid) {
return null;
}
}
return defaultRoom(action, state);
};
ModalContainer.router.getStateForAction = (action, state) => {
if (action.type === 'Navigation/POP' && isSplited()) {
modalRef.dispatch(NavigationActions.navigate({ routeName: 'AuthLoading' }));
setState({ showModal: false });
}
if (action.type === NavigationActions.NAVIGATE && isSplited()) {
const { routeName, params } = action;
if (routeName === 'RoomView') {
Navigation.navigate(routeName, params);
}
}
return defaultModal(action, state);
};
App.router.getStateForAction = (action, state) => {
if (action.type === NavigationActions.NAVIGATE) {
const { routeName, params } = action;
if (routeName === 'InsideStack') {
let commands = defaultCommands;
let newState = { inside: true };
if (isSplited()) {
commands = [...commands, ...keyCommands];
newState = { ...newState, showModal: false };
}
KeyCommands.setKeyCommands(commands);
setState(newState);
}
if (isSplited()) {
if (routeName === 'ReadReceiptsView') {
roomRef.dispatch(NavigationActions.navigate({ routeName, params }));
return null;
}
if (routeName === 'OutsideStack') {
KeyCommands.deleteKeyCommands([...defaultCommands, ...keyCommands]);
setState({ inside: false, showModal: false });
}
if (routeName === 'JitsiMeetView') {
inCall = true;
KeyCommands.deleteKeyCommands([...defaultCommands, ...keyCommands]);
setState({ inside: false, showModal: false });
}
if (routeName === 'OnboardingView') {
KeyCommands.deleteKeyCommands([...defaultCommands, ...keyCommands]);
setState({ inside: false, showModal: false });
}
if (routeName === 'RoomView') {
const resetAction = StackActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName, params })]
});
roomRef.dispatch(resetAction);
notificationRef.dispatch(resetAction);
setState({ showModal: false });
return null;
}
if (routeName === 'NewMessageView') {
modalRef.dispatch(NavigationActions.navigate({ routeName, params }));
setState({ showModal: true });
return null;
}
if (routeName === 'DirectoryView') {
modalRef.dispatch(NavigationActions.navigate({ routeName }));
setState({ showModal: true });
return null;
}
}
}
if (action.type === 'Navigation/TOGGLE_DRAWER' && isSplited()) {
modalRef.dispatch(NavigationActions.navigate({ routeName: 'SettingsView' }));
setState({ showModal: true });
return null;
}
if (action.type === 'Navigation/POP' && inCall) {
KeyCommands.setKeyCommands([...defaultCommands, ...keyCommands]);
setState({ inside: true, showModal: false });
}
return defaultApp(action, state);
};
};
const Split = ({
split, tablet, showModal, closeModal, setModalRef
}) => {
if (split) {
return (
<>
<View style={[sharedStyles.container, sharedStyles.separatorLeft]}>
<RoomContainer ref={ref => roomRef = ref} screenProps={{ split: tablet }} />
</View>
<ModalContainer showModal={showModal} closeModal={closeModal} ref={setModalRef} screenProps={{ split: tablet }} />
</>
);
}
return null;
};
const Tablet = ({
children, tablet, inside, showModal, closeModal, onLayout
}) => {
const setModalRef = (ref) => {
modalRef = ref;
ModalNavigation.setTopLevelNavigator(modalRef);
};
const split = tablet && inside;
return (
<View style={sharedStyles.containerSplitView} onLayout={onLayout}>
<View style={[sharedStyles.container, split && { maxWidth: MAX_SIDEBAR_WIDTH }]}>
{children}
</View>
<Split split={split} tablet={tablet} showModal={showModal} closeModal={closeModal} setModalRef={setModalRef} />
<NotificationContainer ref={ref => notificationRef = ref} />
</View>
);
};
Split.propTypes = {
split: PropTypes.bool,
tablet: PropTypes.bool,
showModal: PropTypes.bool,
closeModal: PropTypes.func,
setModalRef: PropTypes.func
};
Tablet.propTypes = {
children: PropTypes.node,
tablet: PropTypes.bool,
inside: PropTypes.bool,
showModal: PropTypes.bool,
closeModal: PropTypes.func,
onLayout: PropTypes.func
};
export default Tablet;

View File

@ -1,6 +1,8 @@
import { Platform } from 'react-native';
import DeviceInfo from 'react-native-device-info';
import { MIN_WIDTH_SPLIT_LAYOUT } from '../constants/tablet';
const NOTCH_DEVICES = ['iPhone X', 'iPhone XS', 'iPhone XS Max', 'iPhone XR'];
export const isNotch = NOTCH_DEVICES.includes(DeviceInfo.getModel());
@ -9,3 +11,13 @@ export const isAndroid = !isIOS;
export const getReadableVersion = DeviceInfo.getReadableVersion();
export const getBundleId = DeviceInfo.getBundleId();
export const getDeviceModel = DeviceInfo.getModel();
// Tablet info
export const isTablet = DeviceInfo.isTablet();
// We need to use this when app is used on splitview with another app
// to handle cases on app view not-larger sufficient to show splited views (room list/room)
// https://github.com/RocketChat/Rocket.Chat.ReactNative/pull/1300#discussion_r341405245
let _width = null;
export const setWidth = width => _width = width;
export const isSplited = () => isTablet && _width > MIN_WIDTH_SPLIT_LAYOUT;

View File

@ -1,9 +1,11 @@
import { Dimensions } from 'react-native';
import { isTablet } from './deviceInfo';
const { width, height } = Dimensions.get('window');
const guidelineBaseWidth = 375;
const guidelineBaseHeight = 667;
const guidelineBaseWidth = isTablet ? 600 : 375;
const guidelineBaseHeight = isTablet ? 800 : 667;
const scale = size => (width / guidelineBaseWidth) * size;
const verticalScale = size => (height / guidelineBaseHeight) * size;

View File

@ -7,13 +7,14 @@ import { isAndroid } from '../utils/deviceInfo';
const styles = StyleSheet.create({
image: {
width: '100%',
height: '100%'
height: '100%',
backgroundColor: 'white'
}
});
export default React.memo(() => (
<>
<StatusBar />
{isAndroid ? <Image source={{ uri: 'launch_screen' }} style={styles.image} /> : null}
{isAndroid ? <Image source={{ uri: 'launch_screen' }} style={styles.image} resizeMode='contain' /> : null}
</>
));

View File

@ -15,15 +15,22 @@ import SearchBox from '../../containers/SearchBox';
import { CustomIcon } from '../../lib/Icons';
import StatusBar from '../../containers/StatusBar';
import RCActivityIndicator from '../../containers/ActivityIndicator';
import { CloseModalButton } from '../../containers/HeaderButton';
import debounce from '../../utils/debounce';
import log from '../../utils/log';
import Options from './Options';
import styles from './styles';
class DirectoryView extends React.Component {
static navigationOptions = () => ({
title: I18n.t('Directory')
})
static navigationOptions = ({ navigation, screenProps }) => {
const options = {
title: I18n.t('Directory')
};
if (screenProps.split) {
options.headerLeft = <CloseModalButton navigation={navigation} testID='directory-view-close' />;
}
return options;
}
static propTypes = {
navigation: PropTypes.object,
@ -56,16 +63,6 @@ class DirectoryView extends React.Component {
this.setState({ text });
}
onPressItem = (item) => {
const { navigation } = this.props;
try {
const onPressItem = navigation.getParam('onPressItem', () => {});
onPressItem(item);
} catch (error) {
console.log('DirectoryView -> onPressItem -> error', error);
}
}
// eslint-disable-next-line react/sort-comp
load = debounce(async({ newSearch = false }) => {
if (newSearch) {

View File

@ -17,6 +17,7 @@ import I18n from '../i18n';
import { LegalButton } from '../containers/HeaderButton';
import StatusBar from '../containers/StatusBar';
import { COLOR_SEPARATOR, COLOR_BORDER } from '../constants/colors';
import { isTablet } from '../utils/deviceInfo';
const styles = StyleSheet.create({
container: {
@ -407,7 +408,7 @@ class LoginSignupView extends React.Component {
render() {
return (
<ScrollView style={[sharedStyles.containerScrollView, sharedStyles.container, styles.container]} {...scrollPersistTaps}>
<ScrollView style={[sharedStyles.containerScrollView, sharedStyles.container, styles.container, isTablet && sharedStyles.tabletScreenContent]} {...scrollPersistTaps}>
<StatusBar />
<SafeAreaView testID='welcome-view' forceInset={{ vertical: 'never' }} style={styles.safeArea}>
{this.renderServices()}

View File

@ -19,6 +19,7 @@ import { LegalButton } from '../containers/HeaderButton';
import StatusBar from '../containers/StatusBar';
import { COLOR_PRIMARY } from '../constants/colors';
import { animateNextTransition } from '../utils/layoutAnimation';
import { isTablet } from '../utils/deviceInfo';
const styles = StyleSheet.create({
bottomContainer: {
@ -173,7 +174,7 @@ class LoginView extends React.Component {
renderTOTP = () => {
const { isFetching } = this.props;
return (
<SafeAreaView style={sharedStyles.container} testID='login-view' forceInset={{ vertical: 'never' }}>
<SafeAreaView style={[sharedStyles.container, isTablet && sharedStyles.tabletScreenContent]} testID='login-view' forceInset={{ vertical: 'never' }}>
<Text style={[sharedStyles.loginTitle, sharedStyles.textBold, styles.loginTitle]}>{I18n.t('Two_Factor_Authentication')}</Text>
<Text style={[sharedStyles.loginSubtitle, sharedStyles.textRegular]}>{I18n.t('Whats_your_2fa')}</Text>
<TextInput
@ -204,7 +205,7 @@ class LoginView extends React.Component {
Accounts_EmailOrUsernamePlaceholder, Accounts_PasswordPlaceholder, Accounts_PasswordReset, isFetching
} = this.props;
return (
<SafeAreaView style={sharedStyles.container} testID='login-view' forceInset={{ vertical: 'never' }}>
<SafeAreaView style={[sharedStyles.container, isTablet && sharedStyles.tabletScreenContent]} testID='login-view' forceInset={{ vertical: 'never' }}>
<Text style={[sharedStyles.loginTitle, sharedStyles.textBold]}>{I18n.t('Login')}</Text>
<TextInput
autoFocus

View File

@ -5,7 +5,7 @@ import PropTypes from 'prop-types';
import I18n from '../i18n';
import { isIOS } from '../utils/deviceInfo';
export default class TableView extends React.Component {
export default class MarkdownTableView extends React.Component {
static navigationOptions = () => ({
title: I18n.t('Table')
});

View File

@ -18,7 +18,7 @@ import TextInput from '../containers/TextInput';
import I18n from '../i18n';
import { verticalScale, moderateScale } from '../utils/scaling';
import KeyboardView from '../presentation/KeyboardView';
import { isIOS, isNotch } from '../utils/deviceInfo';
import { isIOS, isNotch, isTablet } from '../utils/deviceInfo';
import { CustomIcon } from '../lib/Icons';
import StatusBar from '../containers/StatusBar';
import { COLOR_PRIMARY } from '../constants/colors';
@ -260,28 +260,30 @@ class NewServerView extends React.Component {
<SafeAreaView style={sharedStyles.container} testID='new-server-view'>
<Image style={styles.image} source={{ uri: 'new_server' }} />
<Text style={styles.title}>{I18n.t('Sign_in_your_server')}</Text>
<TextInput
autoFocus={autoFocus}
containerStyle={styles.inputContainer}
placeholder={defaultServer}
value={text}
returnKeyType='send'
onChangeText={this.onChangeText}
testID='new-server-view-input'
onSubmitEditing={this.submit}
clearButtonMode='while-editing'
keyboardType='url'
textContentType='URL'
/>
<Button
title={I18n.t('Connect')}
type='primary'
onPress={this.submit}
disabled={!text}
loading={connecting}
testID='new-server-view-button'
/>
{ isIOS ? this.renderCertificatePicker() : null }
<View style={isTablet && sharedStyles.tabletScreenContent}>
<TextInput
autoFocus={autoFocus}
containerStyle={styles.inputContainer}
placeholder={defaultServer}
value={text}
returnKeyType='send'
onChangeText={this.onChangeText}
testID='new-server-view-input'
onSubmitEditing={this.submit}
clearButtonMode='while-editing'
keyboardType='url'
textContentType='URL'
/>
<Button
title={I18n.t('Connect')}
type='primary'
onPress={this.submit}
disabled={!text}
loading={connecting}
testID='new-server-view-button'
/>
{ isIOS ? this.renderCertificatePicker() : null }
</View>
</SafeAreaView>
</ScrollView>
{this.renderBack()}

View File

@ -13,11 +13,12 @@ import I18n from '../../i18n';
import openLink from '../../utils/openLink';
import Button from './Button';
import styles from './styles';
import { isIOS, isNotch } from '../../utils/deviceInfo';
import { isIOS, isNotch, isTablet } from '../../utils/deviceInfo';
import EventEmitter from '../../utils/events';
import { CustomIcon } from '../../lib/Icons';
import StatusBar from '../../containers/StatusBar';
import { COLOR_PRIMARY, COLOR_WHITE } from '../../constants/colors';
import sharedStyles from '../Styles';
class OnboardingView extends React.Component {
static navigationOptions = () => ({
@ -38,7 +39,9 @@ class OnboardingView extends React.Component {
super(props);
BackHandler.addEventListener('hardwareBackPress', this.handleBackPress);
this.previousServer = props.navigation.getParam('previousServer');
Orientation.lockToPortrait();
if (!isTablet) {
Orientation.lockToPortrait();
}
}
componentDidMount() {
@ -130,7 +133,7 @@ class OnboardingView extends React.Component {
<Image style={styles.onboarding} source={{ uri: 'onboarding' }} fadeDuration={0} />
<Text style={styles.title}>{I18n.t('Welcome_to_RocketChat')}</Text>
<Text style={styles.subtitle}>{I18n.t('Open_Source_Communication')}</Text>
<View style={styles.buttonsContainer}>
<View style={[styles.buttonsContainer, isTablet && sharedStyles.tabletScreenContent]}>
<Button
type='secondary'
title={I18n.t('Connect_to_a_server')}

View File

@ -1,6 +1,7 @@
import { StyleSheet } from 'react-native';
import { verticalScale, moderateScale } from '../../utils/scaling';
import { isTablet } from '../../utils/deviceInfo';
import sharedStyles from '../Styles';
import { COLOR_PRIMARY, COLOR_BORDER, COLOR_WHITE } from '../../constants/colors';
@ -19,6 +20,7 @@ export default StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
justifyContent: isTablet ? 'center' : 'flex-start',
backgroundColor: COLOR_WHITE
},
onboarding: {

View File

@ -7,6 +7,7 @@ import SHA256 from 'js-sha256';
import ImagePicker from 'react-native-image-crop-picker';
import RNPickerSelect from 'react-native-picker-select';
import { SafeAreaView } from 'react-navigation';
import { HeaderBackButton } from 'react-navigation-stack';
import equal from 'deep-equal';
import KeyboardView from '../../presentation/KeyboardView';
@ -27,11 +28,18 @@ import { setUser as setUserAction } from '../../actions/login';
import { CustomIcon } from '../../lib/Icons';
import { DrawerButton } from '../../containers/HeaderButton';
import StatusBar from '../../containers/StatusBar';
import { COLOR_TEXT } from '../../constants/colors';
import { COLOR_TEXT, HEADER_BACK } from '../../constants/colors';
class ProfileView extends React.Component {
static navigationOptions = ({ navigation }) => ({
headerLeft: <DrawerButton navigation={navigation} />,
static navigationOptions = ({ navigation, screenProps }) => ({
headerLeft: screenProps.split ? (
<HeaderBackButton
onPress={() => navigation.navigate('SettingsView')}
tintColor={HEADER_BACK}
/>
) : (
<DrawerButton navigation={navigation} />
),
title: I18n.t('Profile')
})

View File

@ -20,6 +20,7 @@ import isValidEmail from '../utils/isValidEmail';
import { LegalButton } from '../containers/HeaderButton';
import StatusBar from '../containers/StatusBar';
import log from '../utils/log';
import { isTablet } from '../utils/deviceInfo';
const shouldUpdateState = ['name', 'email', 'password', 'username', 'saving'];
@ -186,7 +187,7 @@ class RegisterView extends React.Component {
<KeyboardView contentContainerStyle={sharedStyles.container}>
<StatusBar />
<ScrollView {...scrollPersistTaps} contentContainerStyle={sharedStyles.containerScrollView}>
<SafeAreaView style={sharedStyles.container} testID='register-view' forceInset={{ vertical: 'never' }}>
<SafeAreaView style={[sharedStyles.container, isTablet && sharedStyles.tabletScreenContent]} testID='register-view' forceInset={{ vertical: 'never' }}>
<Text style={[sharedStyles.loginTitle, sharedStyles.textBold]}>{I18n.t('Sign_Up')}</Text>
<TextInput
autoFocus

View File

@ -21,12 +21,19 @@ import { CustomIcon } from '../../lib/Icons';
import DisclosureIndicator from '../../containers/DisclosureIndicator';
import StatusBar from '../../containers/StatusBar';
import { COLOR_WHITE } from '../../constants/colors';
import { CloseModalButton } from '../../containers/HeaderButton';
const renderSeparator = () => <View style={styles.separator} />;
class RoomActionsView extends React.Component {
static navigationOptions = {
title: I18n.t('Actions')
static navigationOptions = ({ navigation, screenProps }) => {
const options = {
title: I18n.t('Actions')
};
if (screenProps.split) {
options.headerLeft = <CloseModalButton navigation={navigation} testID='room-actions-view-close' />;
}
return options;
}
static propTypes = {

View File

@ -10,8 +10,8 @@ const styles = StyleSheet.create({
}
});
const EmptyRoom = React.memo(({ length, mounted }) => {
if (length === 0 && mounted) {
const EmptyRoom = React.memo(({ length, mounted, rid }) => {
if ((length === 0 && mounted) || !rid) {
return <ImageBackground source={{ uri: 'message_empty' }} style={styles.image} />;
}
return null;
@ -19,6 +19,7 @@ const EmptyRoom = React.memo(({ length, mounted }) => {
EmptyRoom.propTypes = {
length: PropTypes.number.isRequired,
rid: PropTypes.string,
mounted: PropTypes.bool
};
export default EmptyRoom;

View File

@ -1,24 +1,26 @@
import React from 'react';
import PropTypes from 'prop-types';
import {
View, Text, StyleSheet, ScrollView
View, Text, StyleSheet, ScrollView, TouchableOpacity
} from 'react-native';
import { shortnameToUnicode } from 'emoji-toolkit';
import removeMarkdown from 'remove-markdown';
import I18n from '../../../i18n';
import sharedStyles from '../../Styles';
import { isIOS, isAndroid } from '../../../utils/deviceInfo';
import { isIOS, isAndroid, isTablet } from '../../../utils/deviceInfo';
import Icon from './Icon';
import { COLOR_TEXT_DESCRIPTION, HEADER_TITLE, COLOR_WHITE } from '../../../constants/colors';
const androidMarginLeft = isTablet ? 0 : 10;
const TITLE_SIZE = 16;
const styles = StyleSheet.create({
container: {
flex: 1,
height: '100%',
marginRight: isAndroid ? 15 : 5,
marginLeft: isAndroid ? 10 : 0
marginLeft: isAndroid ? androidMarginLeft : -12
},
titleContainer: {
flex: 6,
@ -90,12 +92,12 @@ HeaderTitle.propTypes = {
};
const Header = React.memo(({
title, type, status, usersTyping, width, height, prid, tmid, widthOffset, connecting
title, type, status, usersTyping, width, height, prid, tmid, widthOffset, connecting, goRoomActionsView
}) => {
const portrait = height > width;
let scale = 1;
if (!portrait) {
if (!portrait && !tmid) {
if (usersTyping.length > 0) {
scale = 0.8;
}
@ -107,8 +109,14 @@ const Header = React.memo(({
}
}
const onPress = () => {
if (!tmid) {
goRoomActionsView();
}
};
return (
<View style={[styles.container, { width: width - widthOffset }]}>
<TouchableOpacity onPress={onPress} style={[styles.container, { width: width - widthOffset }]}>
<View style={[styles.titleContainer, tmid && styles.threadContainer]}>
<ScrollView
showsHorizontalScrollIndicator={false}
@ -118,9 +126,6 @@ const Header = React.memo(({
>
<Icon type={prid ? 'discussion' : type} status={status} />
<HeaderTitle
prid={prid}
type={type}
status={status}
title={title}
scale={scale}
connecting={connecting}
@ -128,7 +133,7 @@ const Header = React.memo(({
</ScrollView>
</View>
{type === 'thread' ? null : <Typing usersTyping={usersTyping} />}
</View>
</TouchableOpacity>
);
});
@ -142,7 +147,8 @@ Header.propTypes = {
status: PropTypes.string,
usersTyping: PropTypes.array,
widthOffset: PropTypes.number,
connecting: PropTypes.bool
connecting: PropTypes.bool,
goRoomActionsView: PropTypes.func
};
Header.defaultProps = {

View File

@ -1,24 +1,10 @@
import React from 'react';
import { StyleSheet } from 'react-native';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { CustomHeaderButtons, Item } from '../../../containers/HeaderButton';
import database from '../../../lib/database';
const styles = StyleSheet.create({
more: {
marginHorizontal: 0,
marginLeft: 0,
marginRight: 5
},
thread: {
marginHorizontal: 0,
marginLeft: 0,
marginRight: 15
}
});
class RightButtonsContainer extends React.PureComponent {
static propTypes = {
userId: PropTypes.string,
@ -27,8 +13,7 @@ class RightButtonsContainer extends React.PureComponent {
t: PropTypes.string,
tmid: PropTypes.string,
navigation: PropTypes.object,
toggleFollowThread: PropTypes.func,
room: PropTypes.object
toggleFollowThread: PropTypes.func
};
constructor(props) {
@ -75,13 +60,6 @@ class RightButtonsContainer extends React.PureComponent {
navigation.navigate('ThreadMessagesView', { rid, t });
}
goRoomActionsView = () => {
const {
rid, t, navigation, room
} = this.props;
navigation.navigate('RoomActionsView', { rid, t, room });
}
toggleFollowThread = () => {
const { isFollowingThread } = this.state;
const { toggleFollowThread } = this.props;
@ -116,16 +94,8 @@ class RightButtonsContainer extends React.PureComponent {
iconName='thread'
onPress={this.goThreadsView}
testID='room-view-header-threads'
buttonStyle={styles.thread}
/>
) : null}
<Item
title='more'
iconName='menu'
onPress={this.goRoomActionsView}
testID='room-view-header-actions'
buttonStyle={styles.more}
/>
</CustomHeaderButtons>
);
}

View File

@ -0,0 +1,60 @@
import React from 'react';
import PropTypes from 'prop-types';
import { StyleSheet } from 'react-native';
import { HeaderBackButton } from 'react-navigation-stack';
import { isIOS } from '../../../utils/deviceInfo';
import { HEADER_BACK } from '../../../constants/colors';
import Avatar from '../../../containers/Avatar';
const styles = StyleSheet.create({
avatar: {
borderRadius: 10,
marginHorizontal: 16
}
});
const RoomHeaderLeft = ({
tmid, unreadsCount, navigation, baseUrl, userId, token, title, t, goRoomActionsView, split
}) => {
if (!split || tmid) {
return (
<HeaderBackButton
title={unreadsCount > 999 ? '+999' : unreadsCount || ' '}
backTitleVisible={isIOS}
onPress={() => navigation.goBack()}
tintColor={HEADER_BACK}
/>
);
}
if (baseUrl && userId && token) {
return (
<Avatar
text={title}
size={30}
type={t}
baseUrl={baseUrl}
style={styles.avatar}
userId={userId}
token={token}
onPress={goRoomActionsView}
/>
);
}
return null;
};
RoomHeaderLeft.propTypes = {
tmid: PropTypes.string,
unreadsCount: PropTypes.number,
navigation: PropTypes.object,
baseUrl: PropTypes.string,
userId: PropTypes.string,
token: PropTypes.string,
title: PropTypes.string,
t: PropTypes.string,
goRoomActionsView: PropTypes.func,
split: PropTypes.bool
};
export default RoomHeaderLeft;

View File

@ -6,6 +6,7 @@ import equal from 'deep-equal';
import Header from './Header';
import RightButtons from './RightButtons';
import RoomHeaderLeft from './RoomHeaderLeft';
class RoomHeaderView extends Component {
static propTypes = {
@ -17,13 +18,13 @@ class RoomHeaderView extends Component {
window: PropTypes.object,
status: PropTypes.string,
connecting: PropTypes.bool,
widthOffset: PropTypes.number
widthOffset: PropTypes.number,
goRoomActionsView: PropTypes.func
};
shouldComponentUpdate(nextProps) {
const { usersTyping } = this.props;
const {
type, title, status, window, connecting
type, title, status, window, connecting, goRoomActionsView, usersTyping
} = this.props;
if (nextProps.type !== type) {
return true;
@ -46,12 +47,15 @@ class RoomHeaderView extends Component {
if (!equal(nextProps.usersTyping, usersTyping)) {
return true;
}
if (nextProps.goRoomActionsView !== goRoomActionsView) {
return true;
}
return false;
}
render() {
const {
window, title, type, prid, tmid, widthOffset, status = 'offline', connecting, usersTyping
window, title, type, prid, tmid, widthOffset, status = 'offline', connecting, usersTyping, goRoomActionsView
} = this.props;
return (
@ -65,6 +69,7 @@ class RoomHeaderView extends Component {
height={window.height}
usersTyping={usersTyping}
widthOffset={widthOffset}
goRoomActionsView={goRoomActionsView}
connecting={connecting}
/>
);
@ -91,4 +96,4 @@ const mapStateToProps = (state, ownProps) => {
export default responsive(connect(mapStateToProps)(RoomHeaderView));
export { RightButtons };
export { RightButtons, RoomHeaderLeft };

View File

@ -24,6 +24,7 @@ export class List extends React.Component {
rid: PropTypes.string,
t: PropTypes.string,
tmid: PropTypes.string,
listRef: PropTypes.func,
animated: PropTypes.bool
};
@ -63,29 +64,31 @@ export class List extends React.Component {
this.messagesObservable = db.collections
.get('thread_messages')
.query(Q.where('rid', tmid))
.observeWithColumns(['_updated_at']);
} else {
.observe();
} else if (rid) {
this.messagesObservable = db.collections
.get('messages')
.query(Q.where('rid', rid))
.observeWithColumns(['_updated_at']);
.observe();
}
this.unsubscribeMessages();
this.messagesSubscription = this.messagesObservable
.subscribe((data) => {
this.interaction = InteractionManager.runAfterInteractions(() => {
if (tmid) {
data = [this.thread, ...data];
}
const messages = orderBy(data, ['ts'], ['desc']);
if (this.mounted) {
this.setState({ messages }, () => this.debouncedUpdate());
} else {
this.state.messages = messages;
}
if (rid) {
this.unsubscribeMessages();
this.messagesSubscription = this.messagesObservable
.subscribe((data) => {
this.interaction = InteractionManager.runAfterInteractions(() => {
if (tmid) {
data = [this.thread, ...data];
}
const messages = orderBy(data, ['ts'], ['desc']);
if (this.mounted) {
this.setState({ messages }, () => this.update());
} else {
this.state.messages = messages;
}
});
});
});
}
}
// this.state.loading works for this.onEndReached and RoomView.init
@ -117,9 +120,6 @@ export class List extends React.Component {
if (this.onEndReached && this.onEndReached.stop) {
this.onEndReached.stop();
}
if (this.debouncedUpdate && this.debouncedUpdate.stop) {
this.debouncedUpdate.stop();
}
console.countReset(`${ this.constructor.name }.render calls`);
}
@ -155,20 +155,24 @@ export class List extends React.Component {
this.forceUpdate();
};
// eslint-disable-next-line react/sort-comp
debouncedUpdate = debounce(() => {
this.update();
}, 300)
unsubscribeMessages = () => {
if (this.messagesSubscription && this.messagesSubscription.unsubscribe) {
this.messagesSubscription.unsubscribe();
}
}
getLastMessage = () => {
const { messages } = this.state;
if (messages.length > 0) {
return messages[0];
}
return null;
}
renderFooter = () => {
const { loading } = this.state;
if (loading) {
const { rid } = this.props;
if (loading && rid) {
return <ActivityIndicator style={styles.loading} />;
}
return null;
@ -182,13 +186,14 @@ export class List extends React.Component {
render() {
console.count(`${ this.constructor.name }.render calls`);
const { rid, listRef } = this.props;
const { messages } = this.state;
return (
<>
<EmptyRoom length={messages.length} mounted={this.mounted} />
<EmptyRoom rid={rid} length={messages.length} mounted={this.mounted} />
<FlatList
testID='room-view-messages'
ref={ref => this.list = ref}
ref={listRef}
keyExtractor={item => item.id}
data={messages}
extraData={this.state}

View File

@ -8,9 +8,10 @@ import { responsive } from 'react-native-responsive-ui';
import EmojiPicker from '../../containers/EmojiPicker';
import styles from './styles';
import { isAndroid } from '../../utils/deviceInfo';
import { withSplit } from '../../split';
const margin = isAndroid ? 40 : 20;
const tabEmojiStyle = { fontSize: 15 };
const maxSize = 400;
class ReactionPicker extends React.Component {
static propTypes = {
@ -19,15 +20,16 @@ class ReactionPicker extends React.Component {
message: PropTypes.object,
show: PropTypes.bool,
reactionClose: PropTypes.func,
onEmojiSelected: PropTypes.func
onEmojiSelected: PropTypes.func,
split: PropTypes.bool
};
shouldComponentUpdate(nextProps) {
const { show, window } = this.props;
return nextProps.show !== show || window.width !== nextProps.window.width;
const { show, window, split } = this.props;
return nextProps.show !== show || window.width !== nextProps.window.width || nextProps.split !== split;
}
onEmojiSelected(emoji, shortname) {
onEmojiSelected = (emoji, shortname) => {
// standard emojis: `emoji` is unicode and `shortname` is :joy:
// custom emojis: only `emoji` is returned with shortname type (:joy:)
// to set reactions, we need shortname type
@ -37,9 +39,16 @@ class ReactionPicker extends React.Component {
render() {
const {
window: { width, height }, show, baseUrl, reactionClose
window: { width, height }, show, baseUrl, reactionClose, split
} = this.props;
let widthStyle = width - margin;
let heightStyle = Math.min(width, height) - (margin * 2);
if (split) {
widthStyle = maxSize;
heightStyle = maxSize;
}
return (show
? (
<Modal
@ -51,13 +60,18 @@ class ReactionPicker extends React.Component {
animationOut='fadeOut'
>
<View
style={[styles.reactionPickerContainer, { width: width - margin, height: Math.min(width, height) - (margin * 2) }]}
style={[
styles.reactionPickerContainer,
{
width: widthStyle,
height: heightStyle
}
]}
testID='reaction-picker'
>
<EmojiPicker
tabEmojiStyle={tabEmojiStyle}
width={Math.min(width, height) - margin}
onEmojiSelected={(emoji, shortname) => this.onEmojiSelected(emoji, shortname)}
// tabEmojiStyle={tabEmojiStyle}
onEmojiSelected={this.onEmojiSelected}
baseUrl={baseUrl}
/>
</View>
@ -72,4 +86,4 @@ const mapStateToProps = state => ({
baseUrl: state.settings.Site_Url || state.server ? state.server.server : ''
});
export default responsive(connect(mapStateToProps)(ReactionPicker));
export default responsive(connect(mapStateToProps)(withSplit(ReactionPicker)));

View File

@ -94,6 +94,7 @@ class UploadProgress extends Component {
init = () => {
const { rid } = this.props;
if (!rid) { return; }
const db = database.active;
this.uploadsObservable = db.collections

View File

@ -4,7 +4,7 @@ import { Text, View, InteractionManager } from 'react-native';
import { connect } from 'react-redux';
import { RectButton } from 'react-native-gesture-handler';
import { SafeAreaView } from 'react-navigation';
import { HeaderBackButton } from 'react-navigation-stack';
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
import moment from 'moment';
import * as Haptics from 'expo-haptics';
@ -27,17 +27,25 @@ import styles from './styles';
import log from '../../utils/log';
import EventEmitter from '../../utils/events';
import I18n from '../../i18n';
import RoomHeaderView, { RightButtons } from './Header';
import RoomHeaderView, { RightButtons, RoomHeaderLeft } from './Header';
import StatusBar from '../../containers/StatusBar';
import Separator from './Separator';
import { COLOR_WHITE, HEADER_BACK } from '../../constants/colors';
import { COLOR_WHITE } from '../../constants/colors';
import debounce from '../../utils/debounce';
import FileModal from '../../containers/FileModal';
import ReactionsModal from '../../containers/ReactionsModal';
import { LISTENER } from '../../containers/Toast';
import { isReadOnly, isBlocked } from '../../utils/room';
import { isIOS } from '../../utils/deviceInfo';
import { isIOS, isTablet } from '../../utils/deviceInfo';
import { showErrorAlert } from '../../utils/info';
import {
KEY_COMMAND,
handleCommandScroll,
handleCommandRoomActions,
handleCommandSearchMessages,
handleCommandReplyLatest
} from '../../commands';
import ModalNavigation from '../../lib/ModalNavigation';
const stateAttrsUpdate = [
'joined',
@ -55,15 +63,22 @@ const stateAttrsUpdate = [
const roomAttrsUpdate = ['f', 'ro', 'blocked', 'blocker', 'archived', 'muted', 'jitsiTimeout'];
class RoomView extends React.Component {
static navigationOptions = ({ navigation }) => {
const rid = navigation.getParam('rid');
static navigationOptions = ({ navigation, screenProps }) => {
const rid = navigation.getParam('rid', null);
const prid = navigation.getParam('prid');
const title = navigation.getParam('name');
const t = navigation.getParam('t');
const tmid = navigation.getParam('tmid');
const room = navigation.getParam('room');
const baseUrl = navigation.getParam('baseUrl');
const userId = navigation.getParam('userId');
const token = navigation.getParam('token');
const avatar = navigation.getParam('avatar');
const toggleFollowThread = navigation.getParam('toggleFollowThread', () => {});
const goRoomActionsView = navigation.getParam('goRoomActionsView', () => {});
const unreadsCount = navigation.getParam('unreadsCount', null);
if (!rid) {
return null;
}
return {
headerTitle: (
<RoomHeaderView
@ -73,24 +88,30 @@ class RoomView extends React.Component {
title={title}
type={t}
widthOffset={tmid ? 95 : 130}
goRoomActionsView={goRoomActionsView}
/>
),
headerRight: (
<RightButtons
rid={rid}
tmid={tmid}
room={room}
t={t}
navigation={navigation}
toggleFollowThread={toggleFollowThread}
/>
),
headerLeft: (
<HeaderBackButton
title={unreadsCount > 999 ? '+999' : unreadsCount || ' '}
backTitleVisible={isIOS}
onPress={() => navigation.goBack()}
tintColor={HEADER_BACK}
<RoomHeaderLeft
tmid={tmid}
unreadsCount={unreadsCount}
navigation={navigation}
baseUrl={baseUrl}
userId={userId}
token={token}
title={avatar}
t={t}
goRoomActionsView={goRoomActionsView}
split={screenProps.split}
/>
)
};
@ -111,6 +132,7 @@ class RoomView extends React.Component {
Message_Read_Receipt_Enabled: PropTypes.bool,
baseUrl: PropTypes.string,
customEmojis: PropTypes.object,
screenProps: PropTypes.object,
useMarkdown: PropTypes.bool,
replyBroadcast: PropTypes.func
};
@ -124,9 +146,13 @@ class RoomView extends React.Component {
this.tmid = props.navigation.getParam('tmid', null);
const room = props.navigation.getParam('room');
const selectedMessage = props.navigation.getParam('message');
const name = props.navigation.getParam('name');
const fname = props.navigation.getParam('fname');
this.state = {
joined: true,
room: room || { rid: this.rid, t: this.t },
room: room || {
rid: this.rid, t: this.t, name, fname
},
roomUpdate: {},
lastOpen: null,
photoModalVisible: false,
@ -145,7 +171,7 @@ class RoomView extends React.Component {
if (room && room.observe) {
this.observeRoom(room);
} else {
} else if (this.rid) {
this.findAndObserveRoom(this.rid);
}
@ -160,25 +186,38 @@ class RoomView extends React.Component {
componentDidMount() {
this.mounted = true;
this.offset = 0;
this.didMountInteraction = InteractionManager.runAfterInteractions(() => {
const { room } = this.state;
const { navigation, isAuthenticated } = this.props;
if (room.id && !this.tmid) {
navigation.setParams({ name: this.getRoomTitle(room), t: room.t });
const {
navigation, isAuthenticated, user, baseUrl
} = this.props;
if ((room.id || room.rid) && !this.tmid) {
navigation.setParams({
name: this.getRoomTitle(room),
avatar: room.name,
t: room.t,
token: user.token,
userId: user.id,
goRoomActionsView: this.goRoomActionsView,
baseUrl
});
}
if (this.tmid) {
navigation.setParams({ toggleFollowThread: this.toggleFollowThread });
navigation.setParams({ toggleFollowThread: this.toggleFollowThread, goRoomActionsView: this.goRoomActionsView });
}
if (isAuthenticated) {
if (isAuthenticated && this.rid) {
this.init();
} else {
} else if (this.rid) {
EventEmitter.addEventListener('connected', this.handleConnected);
}
if (isIOS) {
if (isIOS && this.rid) {
this.updateUnreadCount();
}
});
if (isTablet) {
EventEmitter.addEventListener(KEY_COMMAND, this.handleCommands);
}
console.timeEnd(`${ this.constructor.name } mount`);
}
@ -199,7 +238,7 @@ class RoomView extends React.Component {
componentDidUpdate(prevProps) {
const { appState } = this.props;
if (appState === 'foreground' && appState !== prevProps.appState) {
if (appState === 'foreground' && appState !== prevProps.appState && this.rid) {
this.onForegroundInteraction = InteractionManager.runAfterInteractions(() => {
this.init();
// Fire List.init() just to keep observables working
@ -265,9 +304,19 @@ class RoomView extends React.Component {
this.queryUnreads.unsubscribe();
}
EventEmitter.removeListener('connected', this.handleConnected);
if (isTablet) {
EventEmitter.removeListener(KEY_COMMAND, this.handleCommands);
}
console.countReset(`${ this.constructor.name }.render calls`);
}
// eslint-disable-next-line react/sort-comp
goRoomActionsView = () => {
const { room } = this.state;
const { navigation } = this.props;
navigation.navigate('RoomActionsView', { rid: this.rid, t: this.t, room });
}
// eslint-disable-next-line react/sort-comp
init = () => {
try {
@ -317,7 +366,7 @@ class RoomView extends React.Component {
if (this.t !== 'd') {
console.log('Room not found');
this.internalSetState({ joined: false });
} else {
} else if (this.rid) {
// We navigate to RoomView before the DM is inserted to the local db
// So we retry just to make sure we have the right content
this.retryFindCount = this.retryFindCount + 1 || 1;
@ -607,11 +656,17 @@ class RoomView extends React.Component {
}
navToRoomInfo = (navParam) => {
const { navigation, user } = this.props;
const { room } = this.state;
const { navigation, user, screenProps } = this.props;
if (navParam.rid === user.id) {
return;
}
navigation.navigate('RoomInfoView', navParam);
if (screenProps && screenProps.split) {
navigation.navigate('RoomActionsView', { rid: this.rid, t: this.t, room });
ModalNavigation.navigate('RoomInfoView', navParam);
} else {
navigation.navigate('RoomInfoView', navParam);
}
}
callJitsi = () => {
@ -624,6 +679,29 @@ class RoomView extends React.Component {
}
};
handleCommands = ({ event }) => {
if (this.rid) {
const { room } = this.state;
const { navigation } = this.props;
const { input } = event;
if (handleCommandScroll(event)) {
const offset = input === 'UIKeyInputUpArrow' ? 100 : -100;
this.offset += offset;
this.flatList.scrollToOffset({ offset: this.offset });
} else if (handleCommandRoomActions(event)) {
navigation.navigate('RoomActionsView', { rid: this.rid, t: this.t, room });
} else if (handleCommandSearchMessages(event)) {
navigation.navigate('RoomActionsView', { rid: this.rid, t: this.t, room });
ModalNavigation.navigate('SearchMessagesView', { rid: this.rid });
} else if (handleCommandReplyLatest(event)) {
if (this.list && this.list.current) {
const message = this.list.current.getLastMessage();
this.onReplyInit(message, false);
}
}
}
}
get isReadOnly() {
const { room } = this.state;
const { user } = this.props;
@ -704,6 +782,9 @@ class RoomView extends React.Component {
} = this.state;
const { navigation } = this.props;
if (!this.rid) {
return null;
}
if (!joined && !this.tmid) {
return (
<View style={styles.joinRoomContainer} key='room-view-join' testID='room-view-join'>
@ -792,6 +873,8 @@ class RoomView extends React.Component {
);
}
setListRef = ref => this.flatList = ref;
render() {
console.count(`${ this.constructor.name }.render calls`);
const {
@ -805,6 +888,7 @@ class RoomView extends React.Component {
<StatusBar />
<List
ref={this.list}
listRef={this.setListRef}
rid={rid}
t={t}
tmid={this.tmid}

View File

@ -34,11 +34,10 @@ export default StyleSheet.create({
marginVertical: 15
},
reactionPickerContainer: {
// width: width - 20,
// height: width - 20,
backgroundColor: '#F7F7F7',
borderRadius: 4,
flexDirection: 'column'
flexDirection: 'column',
overflow: 'hidden'
},
joinRoomContainer: {
justifyContent: 'flex-end',

View File

@ -6,6 +6,9 @@ import {
toggleServerDropdown, closeServerDropdown, closeSortDropdown, setSearch as setSearchAction
} from '../../../actions/rooms';
import Header from './Header';
import EventEmitter from '../../../utils/events';
import { KEY_COMMAND, handleCommandOpenServerDropdown } from '../../../commands';
import { isTablet } from '../../../utils/deviceInfo';
class RoomsListHeaderView extends PureComponent {
static propTypes = {
@ -21,6 +24,24 @@ class RoomsListHeaderView extends PureComponent {
setSearch: PropTypes.func
}
componentDidMount() {
if (isTablet) {
EventEmitter.addEventListener(KEY_COMMAND, this.handleCommands);
}
}
componentWillUnmount() {
if (isTablet) {
EventEmitter.removeListener(KEY_COMMAND, this.handleCommands);
}
}
handleCommands = ({ event }) => {
if (handleCommandOpenServerDropdown(event)) {
this.onPress();
}
}
onSearchChangeText = (text) => {
const { setSearch } = this.props;
setSearch(text.trim());

View File

@ -4,14 +4,15 @@ import PropTypes from 'prop-types';
import SearchBox from '../../../containers/SearchBox';
import { isIOS } from '../../../utils/deviceInfo';
const SearchBar = React.memo(({ onChangeSearchText }) => {
const SearchBar = React.memo(({ onChangeSearchText, inputRef }) => {
if (isIOS) {
return <SearchBox onChangeText={onChangeSearchText} testID='rooms-list-view-search' key='rooms-list-view-search' />;
return <SearchBox onChangeText={onChangeSearchText} inputRef={inputRef} testID='rooms-list-view-search' key='rooms-list-view-search' />;
}
return null;
});
SearchBar.propTypes = {
inputRef: PropTypes.func,
onChangeSearchText: PropTypes.func
};

View File

@ -6,10 +6,10 @@ import Directory from './Directory';
import Sort from './Sort';
const ListHeader = React.memo(({
searchLength, sortBy, onChangeSearchText, toggleSort, goDirectory
searchLength, sortBy, onChangeSearchText, toggleSort, goDirectory, inputRef
}) => (
<>
<SearchBar onChangeSearchText={onChangeSearchText} />
<SearchBar onChangeSearchText={onChangeSearchText} inputRef={inputRef} />
<Directory goDirectory={goDirectory} />
<Sort searchLength={searchLength} sortBy={sortBy} toggleSort={toggleSort} />
</>
@ -20,7 +20,8 @@ ListHeader.propTypes = {
sortBy: PropTypes.string,
onChangeSearchText: PropTypes.func,
toggleSort: PropTypes.func,
goDirectory: PropTypes.func
goDirectory: PropTypes.func,
inputRef: PropTypes.func
};
export default ListHeader;

View File

@ -18,6 +18,9 @@ import I18n from '../../i18n';
import EventEmitter from '../../utils/events';
import Check from '../../containers/Check';
import database from '../../lib/database';
import { KEY_COMMAND, handleCommandSelectServer } from '../../commands';
import { isTablet } from '../../utils/deviceInfo';
import { withSplit } from '../../split';
const ROW_HEIGHT = 68;
const ANIMATION_DURATION = 200;
@ -26,6 +29,7 @@ class ServerDropdown extends Component {
static propTypes = {
navigation: PropTypes.object,
closeServerDropdown: PropTypes.bool,
split: PropTypes.bool,
server: PropTypes.string,
toggleServerDropdown: PropTypes.func,
selectServerRequest: PropTypes.func,
@ -58,6 +62,9 @@ class ServerDropdown extends Component {
useNativeDriver: true
}
).start();
if (isTablet) {
EventEmitter.addEventListener(KEY_COMMAND, this.handleCommands);
}
}
shouldComponentUpdate(nextProps, nextState) {
@ -90,6 +97,9 @@ class ServerDropdown extends Component {
if (this.subscription && this.subscription.unsubscribe) {
this.subscription.unsubscribe();
}
if (isTablet) {
EventEmitter.removeListener(KEY_COMMAND, this.handleCommands);
}
}
close = () => {
@ -116,12 +126,15 @@ class ServerDropdown extends Component {
select = async(server) => {
const {
server: currentServer, selectServerRequest, appStart
server: currentServer, selectServerRequest, appStart, navigation, split
} = this.props;
this.close();
if (currentServer !== server) {
const userId = await RNUserDefaults.get(`${ RocketChat.TOKEN_KEY }-${ server }`);
if (split) {
navigation.navigate('RoomView');
}
if (!userId) {
appStart();
this.newServerTimeout = setTimeout(() => {
@ -133,6 +146,18 @@ class ServerDropdown extends Component {
}
}
handleCommands = ({ event }) => {
const { servers } = this.state;
const { navigation } = this.props;
const { input } = event;
if (handleCommandSelectServer(event)) {
if (servers[input - 1]) {
this.select(servers[input - 1].id);
navigation.navigate('RoomView');
}
}
}
renderSeparator = () => <View style={styles.serverSeparator} />;
renderServer = ({ item }) => {
@ -201,6 +226,7 @@ class ServerDropdown extends Component {
keyExtractor={item => item.id}
renderItem={this.renderServer}
ItemSeparatorComponent={this.renderSeparator}
keyboardShouldPersistTaps='always'
/>
</Animated.View>
]
@ -219,4 +245,4 @@ const mapDispatchToProps = dispatch => ({
appStart: () => dispatch(appStartAction('outside'))
});
export default withNavigation(connect(mapStateToProps, mapDispatchToProps)(ServerDropdown));
export default withNavigation(connect(mapStateToProps, mapDispatchToProps)(withSplit(ServerDropdown)));

View File

@ -6,7 +6,6 @@ import {
BackHandler,
ActivityIndicator,
Text,
ScrollView,
Keyboard,
Dimensions
} from 'react-native';
@ -33,7 +32,7 @@ import {
} from '../../actions/rooms';
import { appStart as appStartAction } from '../../actions';
import debounce from '../../utils/debounce';
import { isIOS, isAndroid } from '../../utils/deviceInfo';
import { isIOS, isAndroid, isTablet } from '../../utils/deviceInfo';
import RoomsListHeaderView from './Header';
import {
DrawerButton,
@ -44,8 +43,29 @@ import StatusBar from '../../containers/StatusBar';
import ListHeader from './ListHeader';
import { selectServerRequest as selectServerRequestAction } from '../../actions/server';
import { animateNextTransition } from '../../utils/layoutAnimation';
import EventEmitter from '../../utils/events';
import {
KEY_COMMAND,
handleCommandShowPreferences,
handleCommandSearching,
handleCommandSelectRoom,
handleCommandPreviousRoom,
handleCommandNextRoom,
handleCommandShowNewMessage,
handleCommandAddNewServer
} from '../../commands';
import { MAX_SIDEBAR_WIDTH } from '../../constants/tablet';
import { withSplit } from '../../split';
const SCROLL_OFFSET = 56;
const INITIAL_NUM_TO_RENDER = isTablet ? 20 : 12;
const CHATS_HEADER = 'Chats';
const UNREAD_HEADER = 'Unread';
const FAVORITES_HEADER = 'Favorites';
const DISCUSSIONS_HEADER = 'Discussions';
const CHANNELS_HEADER = 'Channels';
const DM_HEADER = 'Direct_Messages';
const GROUPS_HEADER = 'Private_Groups';
const shouldUpdateProps = [
'searchText',
@ -58,7 +78,8 @@ const shouldUpdateProps = [
'showUnread',
'useRealName',
'StoreLastMessage',
'appState'
'appState',
'split'
];
const getItemLayout = (data, index) => ({
length: ROW_HEIGHT,
@ -140,7 +161,8 @@ class RoomsListView extends React.Component {
closeSearchHeader: PropTypes.func,
appStart: PropTypes.func,
roomsRequest: PropTypes.func,
closeServerDropdown: PropTypes.func
closeServerDropdown: PropTypes.func,
split: PropTypes.bool
};
constructor(props) {
@ -148,6 +170,7 @@ class RoomsListView extends React.Component {
console.time(`${ this.constructor.name } init`);
console.time(`${ this.constructor.name } mount`);
this.gotSubscriptions = false;
const { width } = Dimensions.get('window');
this.state = {
searching: false,
@ -155,16 +178,24 @@ class RoomsListView extends React.Component {
loading: true,
allChats: [],
chats: [],
unread: [],
favorites: [],
discussions: [],
channels: [],
privateGroup: [],
direct: [],
width
};
}
componentDidMount() {
this.getSubscriptions();
const { navigation, closeServerDropdown } = this.props;
navigation.setParams({
onPressItem: this._onPressItem,
initSearchingAndroid: this.initSearchingAndroid,
cancelSearchingAndroid: this.cancelSearchingAndroid
});
if (isTablet) {
EventEmitter.addEventListener(KEY_COMMAND, this.handleCommands);
}
Dimensions.addEventListener('change', this.onDimensionsChange);
Orientation.unlockAllOrientations();
this.willFocusListener = props.navigation.addListener('willFocus', () => {
this.willFocusListener = navigation.addListener('willFocus', () => {
// Check if there were changes while not focused (it's set on sCU)
if (this.shouldUpdate) {
// animateNextTransition();
@ -172,43 +203,30 @@ class RoomsListView extends React.Component {
this.shouldUpdate = false;
}
});
this.didFocusListener = props.navigation.addListener('didFocus', () => {
BackHandler.addEventListener(
'hardwareBackPress',
this.handleBackPress
);
this.didFocusListener = navigation.addListener('didFocus', () => {
this.backHandler = BackHandler.addEventListener('hardwareBackPress', this.handleBackPress);
});
this.willBlurListener = props.navigation.addListener('willBlur', () => {
props.closeServerDropdown();
BackHandler.addEventListener(
'hardwareBackPress',
this.handleBackPress
);
this.willBlurListener = navigation.addListener('willBlur', () => {
closeServerDropdown();
this.backHandler.remove();
});
}
componentDidMount() {
this.getSubscriptions();
const { navigation } = this.props;
navigation.setParams({
onPressItem: this._onPressItem,
initSearchingAndroid: this.initSearchingAndroid,
cancelSearchingAndroid: this.cancelSearchingAndroid
});
Dimensions.addEventListener('change', this.onDimensionsChange);
console.timeEnd(`${ this.constructor.name } mount`);
}
componentWillReceiveProps(nextProps) {
const { loadingServer, searchText } = this.props;
const { loadingServer, searchText, server } = this.props;
if (nextProps.server && loadingServer !== nextProps.loadingServer) {
if (nextProps.loadingServer) {
this.internalSetState({ loading: true });
this.setState({ loading: true });
} else {
this.getSubscriptions();
}
} else if (searchText !== nextProps.searchText) {
}
if (server && server !== nextProps.server) {
this.gotSubscriptions = false;
}
if (searchText !== nextProps.searchText) {
this.search(nextProps.searchText);
}
}
@ -278,7 +296,7 @@ class RoomsListView extends React.Component {
&& prevProps.showUnread === showUnread
)
) {
this.getSubscriptions();
this.getSubscriptions(true);
} else if (
appState === 'foreground'
&& appState !== prevProps.appState
@ -288,9 +306,6 @@ class RoomsListView extends React.Component {
}
componentWillUnmount() {
if (this.getSubscriptions && this.getSubscriptions.stop) {
this.getSubscriptions.stop();
}
if (this.querySubscription && this.querySubscription.unsubscribe) {
this.querySubscription.unsubscribe();
}
@ -303,6 +318,9 @@ class RoomsListView extends React.Component {
if (this.willBlurListener && this.willBlurListener.remove) {
this.willBlurListener.remove();
}
if (isTablet) {
EventEmitter.removeListener(KEY_COMMAND, this.handleCommands);
}
Dimensions.removeEventListener('change', this.onDimensionsChange);
console.countReset(`${ this.constructor.name }.render calls`);
}
@ -318,11 +336,28 @@ class RoomsListView extends React.Component {
this.setState(...args);
};
getSubscriptions = debounce(async() => {
addRoomsGroup = (data, header, allData) => {
if (data.length > 0) {
if (header) {
allData.push({ rid: header, separator: true });
}
allData = allData.concat(data);
}
return allData;
}
getSubscriptions = async(force = false) => {
if (this.gotSubscriptions && !force) {
return;
}
this.gotSubscriptions = true;
if (this.querySubscription && this.querySubscription.unsubscribe) {
this.querySubscription.unsubscribe();
}
this.setState({ loading: true });
const {
sortBy,
showUnread,
@ -341,13 +376,8 @@ class RoomsListView extends React.Component {
.observeWithColumns(['room_updated_at', 'unread', 'alert', 'user_mentions', 'f', 't']);
this.querySubscription = observable.subscribe((data) => {
let tempChats = [];
let chats = [];
let unread = [];
let favorites = [];
let discussions = [];
let channels = [];
let privateGroup = [];
let direct = [];
if (sortBy === 'alphabetical') {
chats = orderBy(data, ['name'], ['asc']);
} else {
@ -372,41 +402,43 @@ class RoomsListView extends React.Component {
// unread
if (showUnread) {
unread = chats.filter(s => (s.unread > 0 || s.alert) && !s.hideUnreadStatus);
} else {
unread = [];
const unread = chats.filter(s => (s.unread > 0 || s.alert) && !s.hideUnreadStatus);
tempChats = this.addRoomsGroup(unread, UNREAD_HEADER, tempChats);
}
// favorites
if (showFavorites) {
favorites = chats.filter(s => s.f);
} else {
favorites = [];
const favorites = chats.filter(s => s.f);
tempChats = this.addRoomsGroup(favorites, FAVORITES_HEADER, tempChats);
}
// type
if (groupByType) {
discussions = chats.filter(s => s.prid);
channels = chats.filter(s => s.t === 'c' && !s.prid);
privateGroup = chats.filter(s => s.t === 'p' && !s.prid);
direct = chats.filter(s => s.t === 'd' && !s.prid);
const discussions = chats.filter(s => s.prid);
const channels = chats.filter(s => s.t === 'c' && !s.prid);
const privateGroup = chats.filter(s => s.t === 'p' && !s.prid);
const direct = chats.filter(s => s.t === 'd' && !s.prid);
tempChats = this.addRoomsGroup(discussions, DISCUSSIONS_HEADER, tempChats);
tempChats = this.addRoomsGroup(channels, CHANNELS_HEADER, tempChats);
tempChats = this.addRoomsGroup(privateGroup, GROUPS_HEADER, tempChats);
tempChats = this.addRoomsGroup(direct, DM_HEADER, tempChats);
} else if (showUnread) {
chats = chats.filter(s => (!s.unread && !s.alert) || s.hideUnreadStatus);
tempChats = this.addRoomsGroup(chats, CHATS_HEADER, tempChats);
} else if (showFavorites) {
chats = chats.filter(s => !s.f);
tempChats = this.addRoomsGroup(chats, CHATS_HEADER, tempChats);
} else {
tempChats = chats;
}
this.internalSetState({
chats: tempChats,
allChats,
chats,
unread,
favorites,
discussions,
channels,
privateGroup,
direct,
loading: false
});
});
}, 300, true);
}
initSearchingAndroid = () => {
const { openSearchHeader, navigation } = this.props;
@ -422,8 +454,8 @@ class RoomsListView extends React.Component {
navigation.setParams({ searching: false });
closeSearchHeader();
this.internalSetState({ search: [] });
Keyboard.dismiss();
}
Keyboard.dismiss();
};
handleBackPress = () => {
@ -453,6 +485,7 @@ class RoomsListView extends React.Component {
goRoom = (item) => {
this.cancelSearchingAndroid();
const { navigation } = this.props;
this.item = item;
navigation.navigate('RoomView', {
rid: item.rid,
name: this.getRoomTitle(item),
@ -569,6 +602,70 @@ class RoomsListView extends React.Component {
navigation.navigate('DirectoryView');
};
goRoomByIndex = (index) => {
const { chats } = this.state;
const filteredChats = chats.filter(c => !c.separator);
const room = filteredChats[index - 1];
if (room) {
this.goRoom(room);
}
}
findOtherRoom = (index, sign) => {
const { chats } = this.state;
const otherIndex = index + sign;
const otherRoom = chats[otherIndex];
if (!otherRoom) {
return;
}
if (otherRoom.separator) {
return this.findOtherRoom(otherIndex, sign);
} else {
return otherRoom;
}
}
// Go to previous or next room based on sign (-1 or 1)
// It's used by iPad key commands
goOtherRoom = (sign) => {
if (!this.item) {
return;
}
// Don't run during search
const { search } = this.state;
if (search.length > 0) {
return;
}
const { chats } = this.state;
const index = chats.findIndex(c => c.rid === this.item.rid);
const otherRoom = this.findOtherRoom(index, sign);
if (otherRoom) {
this.goRoom(otherRoom);
}
}
handleCommands = ({ event }) => {
const { navigation, server } = this.props;
const { input } = event;
if (handleCommandShowPreferences(event)) {
navigation.toggleDrawer();
} else if (handleCommandSearching(event)) {
this.scroll.scrollToOffset({ animated: true, offset: 0 });
this.inputRef.focus();
} else if (handleCommandSelectRoom(event)) {
this.goRoomByIndex(input);
} else if (handleCommandPreviousRoom(event)) {
this.goOtherRoom(-1);
} else if (handleCommandNextRoom(event)) {
this.goOtherRoom(1);
} else if (handleCommandShowNewMessage(event)) {
navigation.navigate('NewMessageView', { onPressItem: this._onPressItem });
} else if (handleCommandAddNewServer(event)) {
navigation.navigate('OnboardingView', { previousServer: server });
}
};
getScrollRef = ref => (this.scroll = ref);
renderListHeader = () => {
@ -576,6 +673,7 @@ class RoomsListView extends React.Component {
const { sortBy } = this.props;
return (
<ListHeader
inputRef={(ref) => { this.inputRef = ref; }}
searchLength={search.length}
sortBy={sortBy}
onChangeSearchText={this.search}
@ -592,13 +690,18 @@ class RoomsListView extends React.Component {
};
renderItem = ({ item }) => {
if (item.separator) {
return this.renderSectionHeader(item.rid);
}
const { width } = this.state;
const {
userId,
username,
token,
baseUrl,
StoreLastMessage
StoreLastMessage,
split
} = this.props;
const id = item.rid.replace(userId, '').trim();
@ -626,7 +729,7 @@ class RoomsListView extends React.Component {
showLastMessage={StoreLastMessage}
onPress={() => this._onPressItem(item)}
testID={`rooms-list-view-item-${ item.name }`}
width={width}
width={split ? MAX_SIDEBAR_WIDTH : width}
toggleFav={this.toggleFav}
toggleRead={this.toggleRead}
hideChannel={this.hideChannel}
@ -640,129 +743,29 @@ class RoomsListView extends React.Component {
</View>
);
renderSection = (data, header) => {
const { showUnread, showFavorites, groupByType } = this.props;
if (header === 'Unread' && !showUnread) {
return null;
} else if (header === 'Favorites' && !showFavorites) {
return null;
} else if (
[
'Discussions',
'Channels',
'Direct_Messages',
'Private_Groups'
].includes(header)
&& !groupByType
) {
return null;
} else if (header === 'Chats' && groupByType) {
return null;
}
if (data && data.length > 0) {
return (
<FlatList
data={data}
extraData={data}
keyExtractor={keyExtractor}
style={styles.list}
renderItem={this.renderItem}
ListHeaderComponent={() => this.renderSectionHeader(header)}
getItemLayout={getItemLayout}
enableEmptySections
removeClippedSubviews={isIOS}
keyboardShouldPersistTaps='always'
initialNumToRender={12}
windowSize={7}
/>
);
}
return null;
};
renderList = () => {
const {
search,
chats,
unread,
favorites,
discussions,
channels,
direct,
privateGroup
} = this.state;
if (search.length > 0) {
return (
<FlatList
data={search}
extraData={search}
keyExtractor={keyExtractor}
style={styles.list}
renderItem={this.renderItem}
getItemLayout={getItemLayout}
enableEmptySections
removeClippedSubviews={isIOS}
keyboardShouldPersistTaps='always'
initialNumToRender={12}
windowSize={7}
/>
);
}
return (
<View style={styles.container}>
{this.renderSection(unread, 'Unread')}
{this.renderSection(favorites, 'Favorites')}
{this.renderSection(discussions, 'Discussions')}
{this.renderSection(channels, 'Channels')}
{this.renderSection(direct, 'Direct_Messages')}
{this.renderSection(privateGroup, 'Private_Groups')}
{this.renderSection(chats, 'Chats')}
</View>
);
};
renderScroll = () => {
const { loading } = this.state;
const { loading, chats, search } = this.state;
if (loading) {
return <ActivityIndicator style={styles.loading} />;
}
const { showUnread, showFavorites, groupByType } = this.props;
if (!(showUnread || showFavorites || groupByType)) {
const { chats, search } = this.state;
return (
<FlatList
ref={this.getScrollRef}
data={search.length ? search : chats}
extraData={search.length ? search : chats}
contentOffset={isIOS ? { x: 0, y: SCROLL_OFFSET } : {}}
keyExtractor={keyExtractor}
style={styles.list}
renderItem={this.renderItem}
ListHeaderComponent={this.renderListHeader}
getItemLayout={getItemLayout}
removeClippedSubviews={isIOS}
keyboardShouldPersistTaps='always'
initialNumToRender={9}
windowSize={9}
/>
);
}
return (
<ScrollView
<FlatList
ref={this.getScrollRef}
data={search.length ? search : chats}
extraData={search.length ? search : chats}
contentOffset={isIOS ? { x: 0, y: SCROLL_OFFSET } : {}}
keyExtractor={keyExtractor}
style={styles.list}
renderItem={this.renderItem}
ListHeaderComponent={this.renderListHeader}
getItemLayout={getItemLayout}
removeClippedSubviews={isIOS}
keyboardShouldPersistTaps='always'
testID='rooms-list-view-list'
>
{this.renderListHeader()}
{this.renderList()}
</ScrollView>
initialNumToRender={INITIAL_NUM_TO_RENDER}
windowSize={9}
/>
);
};
@ -829,4 +832,4 @@ const mapDispatchToProps = dispatch => ({
closeServerDropdown: () => dispatch(closeServerDropdownAction())
});
export default connect(mapStateToProps, mapDispatchToProps)(RoomsListView);
export default connect(mapStateToProps, mapDispatchToProps)(withSplit(RoomsListView));

View File

@ -17,6 +17,7 @@ import I18n from '../i18n';
import RocketChat from '../lib/rocketchat';
import StatusBar from '../containers/StatusBar';
import log from '../utils/log';
import { isTablet } from '../utils/deviceInfo';
const styles = StyleSheet.create({
loginTitle: {
@ -49,7 +50,9 @@ class SetUsernameView extends React.Component {
};
const { server } = this.props;
props.navigation.setParams({ title: server });
Orientation.lockToPortrait();
if (!isTablet) {
Orientation.lockToPortrait();
}
}
async componentDidMount() {

View File

@ -5,17 +5,20 @@ import {
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { logout as logoutAction } from '../../actions/login';
import { toggleMarkdown as toggleMarkdownAction } from '../../actions/markdown';
import { toggleCrashReport as toggleCrashReportAction } from '../../actions/crashReport';
import { SWITCH_TRACK_COLOR } from '../../constants/colors';
import { DrawerButton } from '../../containers/HeaderButton';
import { SWITCH_TRACK_COLOR, COLOR_DANGER } from '../../constants/colors';
import { DrawerButton, CloseModalButton } from '../../containers/HeaderButton';
import StatusBar from '../../containers/StatusBar';
import ListItem from '../../containers/ListItem';
import { DisclosureImage } from '../../containers/DisclosureIndicator';
import Separator from '../../containers/Separator';
import I18n from '../../i18n';
import { MARKDOWN_KEY, CRASH_REPORT_KEY } from '../../lib/rocketchat';
import { getReadableVersion, getDeviceModel, isAndroid } from '../../utils/deviceInfo';
import {
getReadableVersion, getDeviceModel, isAndroid
} from '../../utils/deviceInfo';
import openLink from '../../utils/openLink';
import scrollPersistTaps from '../../utils/scrollPersistTaps';
import { showErrorAlert } from '../../utils/info';
@ -23,6 +26,9 @@ import styles from './styles';
import sharedStyles from '../Styles';
import { loggerConfig, analytics } from '../../utils/log';
import { PLAY_MARKET_LINK, APP_STORE_LINK, LICENSE_LINK } from '../../constants/links';
import SidebarView from '../SidebarView';
import { withSplit } from '../../split';
import Navigation from '../../lib/Navigation';
const SectionSeparator = React.memo(() => <View style={styles.sectionSeparatorBorder} />);
const ItemInfo = React.memo(({ info }) => (
@ -35,8 +41,12 @@ ItemInfo.propTypes = {
};
class SettingsView extends React.Component {
static navigationOptions = ({ navigation }) => ({
headerLeft: <DrawerButton navigation={navigation} />,
static navigationOptions = ({ navigation, screenProps }) => ({
headerLeft: screenProps.split ? (
<CloseModalButton navigation={navigation} testID='settings-view-close' />
) : (
<DrawerButton navigation={navigation} />
),
title: I18n.t('Settings')
});
@ -46,7 +56,17 @@ class SettingsView extends React.Component {
useMarkdown: PropTypes.bool,
allowCrashReport: PropTypes.bool,
toggleMarkdown: PropTypes.func,
toggleCrashReport: PropTypes.func
toggleCrashReport: PropTypes.func,
split: PropTypes.bool,
logout: PropTypes.func.isRequired
}
logout = () => {
const { logout, split } = this.props;
if (split) {
Navigation.navigate('RoomView');
}
logout();
}
toggleMarkdown = (value) => {
@ -96,6 +116,21 @@ class SettingsView extends React.Component {
renderDisclosure = () => <DisclosureImage />
renderLogout = () => (
<>
<Separator />
<ListItem
title={I18n.t('Logout')}
testID='settings-logout'
onPress={this.logout}
right={this.renderDisclosure}
color={COLOR_DANGER}
/>
<Separator />
<ItemInfo />
</>
);
renderMarkdownSwitch = () => {
const { useMarkdown } = this.props;
return (
@ -119,7 +154,7 @@ class SettingsView extends React.Component {
}
render() {
const { server } = this.props;
const { server, split } = this.props;
return (
<SafeAreaView style={sharedStyles.listSafeArea} testID='settings-view'>
<StatusBar />
@ -129,6 +164,21 @@ class SettingsView extends React.Component {
showsVerticalScrollIndicator={false}
testID='settings-view-list'
>
{split ? (
<>
<SidebarView />
<SectionSeparator />
<ListItem
title={I18n.t('Profile')}
onPress={() => this.navigateToRoom('ProfileView')}
showActionIndicator
testID='settings-profile'
right={this.renderDisclosure}
/>
<Separator />
</>
) : null}
<ListItem
title={I18n.t('Contact_us')}
onPress={this.sendEmail}
@ -198,6 +248,8 @@ class SettingsView extends React.Component {
<ItemInfo
info={I18n.t('Crash_report_disclaimer')}
/>
{ split ? this.renderLogout() : null }
</ScrollView>
</SafeAreaView>
);
@ -211,8 +263,9 @@ const mapStateToProps = state => ({
});
const mapDispatchToProps = dispatch => ({
logout: () => dispatch(logoutAction()),
toggleMarkdown: params => dispatch(toggleMarkdownAction(params)),
toggleCrashReport: params => dispatch(toggleCrashReportAction(params))
});
export default connect(mapStateToProps, mapDispatchToProps)(SettingsView);
export default connect(mapStateToProps, mapDispatchToProps)(withSplit(SettingsView));

View File

@ -21,6 +21,7 @@ import SidebarItem from './SidebarItem';
import { COLOR_TEXT } from '../../constants/colors';
import database from '../../lib/database';
import { animateNextTransition } from '../../utils/layoutAnimation';
import { withSplit } from '../../split';
const keyExtractor = item => item.id;
@ -41,7 +42,8 @@ class Sidebar extends Component {
user: PropTypes.object,
logout: PropTypes.func.isRequired,
activeItemKey: PropTypes.string,
loadingServer: PropTypes.bool
loadingServer: PropTypes.bool,
split: PropTypes.bool
}
constructor(props) {
@ -71,7 +73,7 @@ class Sidebar extends Component {
shouldComponentUpdate(nextProps, nextState) {
const { status, showStatus, isAdmin } = this.state;
const {
Site_Name, user, baseUrl, activeItemKey
Site_Name, user, baseUrl, activeItemKey, split
} = this.props;
if (nextState.showStatus !== showStatus) {
return true;
@ -99,6 +101,9 @@ class Sidebar extends Component {
return true;
}
}
if (nextProps.split !== split) {
return true;
}
if (!equal(nextState.status, status)) {
return true;
}
@ -242,7 +247,9 @@ class Sidebar extends Component {
render() {
const { showStatus } = this.state;
const { user, Site_Name, baseUrl } = this.props;
const {
user, Site_Name, baseUrl, split
} = this.props;
if (!user) {
return null;
@ -275,9 +282,9 @@ class Sidebar extends Component {
<CustomIcon name='arrow-down' size={20} style={[styles.headerIcon, showStatus && styles.inverted]} />
</RectButton>
<Separator key='separator-header' />
{!split || showStatus ? <Separator key='separator-header' /> : null}
{!showStatus ? this.renderNavigation() : null}
{!showStatus && !split ? this.renderNavigation() : null}
{showStatus ? this.renderStatus() : null}
</ScrollView>
</SafeAreaView>
@ -303,4 +310,4 @@ const mapDispatchToProps = dispatch => ({
logout: () => dispatch(logoutAction())
});
export default connect(mapStateToProps, mapDispatchToProps)(Sidebar);
export default connect(mapStateToProps, mapDispatchToProps)(withSplit(Sidebar));

View File

@ -3,6 +3,7 @@ import { StyleSheet, Platform } from 'react-native';
import {
COLOR_DANGER, COLOR_BUTTON_PRIMARY, COLOR_SEPARATOR, COLOR_TEXT, COLOR_TEXT_DESCRIPTION, COLOR_TITLE, COLOR_BACKGROUND_CONTAINER, COLOR_WHITE, COLOR_PRIMARY, HEADER_BACK
} from '../constants/colors';
import { MAX_SCREEN_CONTENT_WIDTH, MAX_CONTENT_WIDTH } from '../constants/tablet';
export default StyleSheet.create({
root: {
@ -16,6 +17,26 @@ export default StyleSheet.create({
padding: 15,
paddingBottom: 30
},
containerSplitView: {
flex: 1,
flexDirection: 'row'
},
tabletContent: {
maxWidth: MAX_CONTENT_WIDTH
},
tabletScreenContent: {
alignSelf: 'center',
width: MAX_SCREEN_CONTENT_WIDTH
},
modal: {
// Following UIModalPresentationFormSheet size
// this not change on different iPad sizes
width: 540,
height: 620,
alignSelf: 'center',
borderRadius: 10,
overflow: 'hidden'
},
buttonContainerLastChild: {
marginBottom: 40
},
@ -117,6 +138,10 @@ export default StyleSheet.create({
borderTopWidth: StyleSheet.hairlineWidth,
borderBottomWidth: StyleSheet.hairlineWidth
},
separatorLeft: {
borderColor: COLOR_SEPARATOR,
borderLeftWidth: StyleSheet.hairlineWidth
},
textRegular: {
backgroundColor: 'transparent',
...Platform.select({

View File

@ -21,6 +21,7 @@ import buildMessage from '../../lib/methods/helpers/buildMessage';
import log from '../../utils/log';
import debounce from '../../utils/debounce';
import protectedFunction from '../../lib/methods/helpers/protectedFunction';
import ModalNavigation from '../../lib/ModalNavigation';
const Separator = React.memo(() => <View style={styles.separator} />);
const API_FETCH_COUNT = 50;
@ -35,7 +36,8 @@ class ThreadMessagesView extends React.Component {
navigation: PropTypes.object,
baseUrl: PropTypes.string,
useRealName: PropTypes.bool,
customEmojis: PropTypes.object
customEmojis: PropTypes.object,
screenProps: PropTypes.object
}
constructor(props) {
@ -258,11 +260,16 @@ class ThreadMessagesView extends React.Component {
)
navToRoomInfo = (navParam) => {
const { navigation, user } = this.props;
const { navigation, user, screenProps } = this.props;
if (navParam.rid === user.id) {
return;
}
navigation.navigate('RoomInfoView', navParam);
if (screenProps && screenProps.split) {
navigation.navigate('RoomActionsView', { rid: this.rid, t: this.t });
ModalNavigation.navigate('RoomInfoView', navParam);
} else {
navigation.navigate('RoomInfoView', navParam);
}
}
renderItem = ({ item }) => {

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
<viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Launch Screen Icon" translatesAutoresizingMaskIntoConstraints="NO" id="OgI-vW-r9q">
<rect key="frame" x="133" y="286" width="109" height="95"/>
<constraints>
<constraint firstAttribute="width" constant="109" id="OdC-6s-bFk"/>
<constraint firstAttribute="height" constant="95" id="aPz-Zh-jVS"/>
</constraints>
</imageView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="OgI-vW-r9q" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="6rJ-eg-g9T"/>
<constraint firstItem="OgI-vW-r9q" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="If3-ka-9Gs"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
<resources>
<image name="Launch Screen Icon" width="109" height="95"/>
</resources>
</document>

View File

@ -102,6 +102,8 @@ PODS:
- GoogleUtilities/UserDefaults (6.3.0):
- GoogleUtilities/Logger
- JitsiMeetSDK (2.4.0)
- KeyCommands (2.0.3):
- React
- libwebp (1.0.3):
- libwebp/demux (= 1.0.3)
- libwebp/mux (= 1.0.3)
@ -418,6 +420,7 @@ DEPENDENCIES:
- Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`)
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
- JitsiMeetSDK (from `https://github.com/RocketChat/jitsi-meet-ios-sdk-releases.git`)
- KeyCommands (from `../node_modules/react-native-keycommands`)
- RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
- React (from `../node_modules/react-native/`)
@ -536,6 +539,8 @@ EXTERNAL SOURCES:
:podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec"
JitsiMeetSDK:
:git: https://github.com/RocketChat/jitsi-meet-ios-sdk-releases.git
KeyCommands:
:path: "../node_modules/react-native-keycommands"
RCTRequired:
:path: "../node_modules/react-native/Libraries/RCTRequired"
RCTTypeSafety:
@ -694,6 +699,7 @@ SPEC CHECKSUMS:
GoogleDataTransportCCTSupport: 7455d07b98851aa63e4c05a34dad356ca588479e
GoogleUtilities: 9c2c544202301110b29f7974a82e77fdcf12bf51
JitsiMeetSDK: d4a3aeed1a75fd57e6a78e5d202b6051dfcb9320
KeyCommands: f66c535f698ed14b3d3a4e58859d79a827ea907e
libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e
nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48
QBImagePickerController: d54cf93db6decf26baf6ed3472f336ef35cae022

View File

@ -0,0 +1 @@
../../../../../node_modules/react-native-keycommands/ios/KeyCommands/RCTKeyCommandConstants.h

View File

@ -0,0 +1 @@
../../../../../node_modules/react-native-keycommands/ios/KeyCommands/RCTKeyCommandsManager.h

View File

@ -0,0 +1 @@
../../../../../node_modules/react-native-keycommands/ios/KeyCommands/RCTKeyCommandConstants.h

View File

@ -0,0 +1 @@
../../../../../node_modules/react-native-keycommands/ios/KeyCommands/RCTKeyCommandsManager.h

View File

@ -0,0 +1,21 @@
{
"name": "KeyCommands",
"version": "2.0.3",
"summary": "iOS UIKeyCommands.",
"description": "iOS UIKeyCommands.",
"license": "MIT",
"authors": "djorkaeffalexandre",
"homepage": "https://github.com/RocketChat/react-native-keycommands",
"source": {
"git": "https://github.com/RocketChat/react-native-keycommands.git"
},
"platforms": {
"ios": "7.0"
},
"source_files": "ios/**/*.{h,m}",
"dependencies": {
"React": [
]
}
}

View File

@ -102,6 +102,8 @@ PODS:
- GoogleUtilities/UserDefaults (6.3.0):
- GoogleUtilities/Logger
- JitsiMeetSDK (2.4.0)
- KeyCommands (2.0.3):
- React
- libwebp (1.0.3):
- libwebp/demux (= 1.0.3)
- libwebp/mux (= 1.0.3)
@ -418,6 +420,7 @@ DEPENDENCIES:
- Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`)
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
- JitsiMeetSDK (from `https://github.com/RocketChat/jitsi-meet-ios-sdk-releases.git`)
- KeyCommands (from `../node_modules/react-native-keycommands`)
- RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
- React (from `../node_modules/react-native/`)
@ -536,6 +539,8 @@ EXTERNAL SOURCES:
:podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec"
JitsiMeetSDK:
:git: https://github.com/RocketChat/jitsi-meet-ios-sdk-releases.git
KeyCommands:
:path: "../node_modules/react-native-keycommands"
RCTRequired:
:path: "../node_modules/react-native/Libraries/RCTRequired"
RCTTypeSafety:
@ -694,6 +699,7 @@ SPEC CHECKSUMS:
GoogleDataTransportCCTSupport: 7455d07b98851aa63e4c05a34dad356ca588479e
GoogleUtilities: 9c2c544202301110b29f7974a82e77fdcf12bf51
JitsiMeetSDK: d4a3aeed1a75fd57e6a78e5d202b6051dfcb9320
KeyCommands: f66c535f698ed14b3d3a4e58859d79a827ea907e
libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e
nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48
QBImagePickerController: d54cf93db6decf26baf6ed3472f336ef35cae022

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
#import <Foundation/Foundation.h>
@interface PodsDummy_KeyCommands : NSObject
@end
@implementation PodsDummy_KeyCommands
@end

View File

@ -0,0 +1,12 @@
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif

View File

@ -0,0 +1,11 @@
APPLICATION_EXTENSION_API_ONLY = YES
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/KeyCommands
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/KeyCommands" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/DoubleConversion" "${PODS_ROOT}/Headers/Public/KeyCommands" "${PODS_ROOT}/Headers/Public/React-Core" "${PODS_ROOT}/Headers/Public/React-RCTBlob" "${PODS_ROOT}/Headers/Public/React-RCTText" "${PODS_ROOT}/Headers/Public/React-cxxreact" "${PODS_ROOT}/Headers/Public/React-jsi" "${PODS_ROOT}/Headers/Public/React-jsiexecutor" "${PODS_ROOT}/Headers/Public/React-jsinspector" "${PODS_ROOT}/Headers/Public/Yoga" "${PODS_ROOT}/Headers/Public/glog"
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/../../node_modules/react-native-keycommands
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES

View File

@ -1,9 +1,9 @@
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Crashlytics/iOS" "${PODS_ROOT}/Fabric/iOS" "${PODS_ROOT}/FirebaseAnalytics/Frameworks" "${PODS_ROOT}/GoogleAppMeasurement/Frameworks" "${PODS_ROOT}/JitsiMeetSDK/Frameworks"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) SD_WEBP=1 $(inherited) PB_FIELD_32BIT=1 PB_NO_PACKED_STRUCTS=1 PB_ENABLE_MALLOC=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/BugsnagReactNative" "${PODS_ROOT}/Headers/Public/DoubleConversion" "${PODS_ROOT}/Headers/Public/EXAV" "${PODS_ROOT}/Headers/Public/EXAppLoaderProvider" "${PODS_ROOT}/Headers/Public/EXConstants" "${PODS_ROOT}/Headers/Public/EXFileSystem" "${PODS_ROOT}/Headers/Public/EXHaptics" "${PODS_ROOT}/Headers/Public/EXPermissions" "${PODS_ROOT}/Headers/Public/EXWebBrowser" "${PODS_ROOT}/Headers/Public/FBLazyVector" "${PODS_ROOT}/Headers/Public/FBReactNativeSpec" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseCoreDiagnostics" "${PODS_ROOT}/Headers/Public/FirebaseCoreDiagnosticsInterop" "${PODS_ROOT}/Headers/Public/FirebaseInstanceID" "${PODS_ROOT}/Headers/Public/GoogleDataTransport" "${PODS_ROOT}/Headers/Public/GoogleDataTransportCCTSupport" "${PODS_ROOT}/Headers/Public/GoogleUtilities" "${PODS_ROOT}/Headers/Public/QBImagePickerController" "${PODS_ROOT}/Headers/Public/RCTRequired" "${PODS_ROOT}/Headers/Public/RCTTypeSafety" "${PODS_ROOT}/Headers/Public/RNAudio" "${PODS_ROOT}/Headers/Public/RNDeviceInfo" "${PODS_ROOT}/Headers/Public/RNFastImage" "${PODS_ROOT}/Headers/Public/RNFirebase" "${PODS_ROOT}/Headers/Public/RNGestureHandler" "${PODS_ROOT}/Headers/Public/RNImageCropPicker" "${PODS_ROOT}/Headers/Public/RNLocalize" "${PODS_ROOT}/Headers/Public/RNReanimated" "${PODS_ROOT}/Headers/Public/RNScreens" "${PODS_ROOT}/Headers/Public/RNUserDefaults" "${PODS_ROOT}/Headers/Public/RNVectorIcons" "${PODS_ROOT}/Headers/Public/RSKImageCropper" "${PODS_ROOT}/Headers/Public/React-Core" "${PODS_ROOT}/Headers/Public/React-RCTBlob" "${PODS_ROOT}/Headers/Public/React-RCTText" "${PODS_ROOT}/Headers/Public/React-cxxreact" "${PODS_ROOT}/Headers/Public/React-jsi" "${PODS_ROOT}/Headers/Public/React-jsiexecutor" "${PODS_ROOT}/Headers/Public/React-jsinspector" "${PODS_ROOT}/Headers/Public/ReactCommon" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SDWebImageWebPCoder" "${PODS_ROOT}/Headers/Public/UMBarCodeScannerInterface" "${PODS_ROOT}/Headers/Public/UMCameraInterface" "${PODS_ROOT}/Headers/Public/UMConstantsInterface" "${PODS_ROOT}/Headers/Public/UMCore" "${PODS_ROOT}/Headers/Public/UMFaceDetectorInterface" "${PODS_ROOT}/Headers/Public/UMFileSystemInterface" "${PODS_ROOT}/Headers/Public/UMFontInterface" "${PODS_ROOT}/Headers/Public/UMImageLoaderInterface" "${PODS_ROOT}/Headers/Public/UMPermissionsInterface" "${PODS_ROOT}/Headers/Public/UMReactNativeAdapter" "${PODS_ROOT}/Headers/Public/UMSensorsInterface" "${PODS_ROOT}/Headers/Public/UMTaskManagerInterface" "${PODS_ROOT}/Headers/Public/Yoga" "${PODS_ROOT}/Headers/Public/glog" "${PODS_ROOT}/Headers/Public/libwebp" "${PODS_ROOT}/Headers/Public/nanopb" "${PODS_ROOT}/Headers/Public/react-native-background-timer" "${PODS_ROOT}/Headers/Public/react-native-document-picker" "${PODS_ROOT}/Headers/Public/react-native-jitsi-meet" "${PODS_ROOT}/Headers/Public/react-native-keyboard-input" "${PODS_ROOT}/Headers/Public/react-native-keyboard-tracking-view" "${PODS_ROOT}/Headers/Public/react-native-notifications" "${PODS_ROOT}/Headers/Public/react-native-orientation-locker" "${PODS_ROOT}/Headers/Public/react-native-slider" "${PODS_ROOT}/Headers/Public/react-native-splash-screen" "${PODS_ROOT}/Headers/Public/react-native-video" "${PODS_ROOT}/Headers/Public/react-native-webview" "${PODS_ROOT}/Headers/Public/rn-extensions-share" "${PODS_ROOT}/Headers/Public/rn-fetch-blob" $(inherited) ${PODS_ROOT}/Firebase/CoreOnly/Sources "$(PODS_ROOT)/Headers/Private/React-Core"
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/BugsnagReactNative" "${PODS_ROOT}/Headers/Public/DoubleConversion" "${PODS_ROOT}/Headers/Public/EXAV" "${PODS_ROOT}/Headers/Public/EXAppLoaderProvider" "${PODS_ROOT}/Headers/Public/EXConstants" "${PODS_ROOT}/Headers/Public/EXFileSystem" "${PODS_ROOT}/Headers/Public/EXHaptics" "${PODS_ROOT}/Headers/Public/EXPermissions" "${PODS_ROOT}/Headers/Public/EXWebBrowser" "${PODS_ROOT}/Headers/Public/FBLazyVector" "${PODS_ROOT}/Headers/Public/FBReactNativeSpec" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseCoreDiagnostics" "${PODS_ROOT}/Headers/Public/FirebaseCoreDiagnosticsInterop" "${PODS_ROOT}/Headers/Public/FirebaseInstanceID" "${PODS_ROOT}/Headers/Public/GoogleDataTransport" "${PODS_ROOT}/Headers/Public/GoogleDataTransportCCTSupport" "${PODS_ROOT}/Headers/Public/GoogleUtilities" "${PODS_ROOT}/Headers/Public/KeyCommands" "${PODS_ROOT}/Headers/Public/QBImagePickerController" "${PODS_ROOT}/Headers/Public/RCTRequired" "${PODS_ROOT}/Headers/Public/RCTTypeSafety" "${PODS_ROOT}/Headers/Public/RNAudio" "${PODS_ROOT}/Headers/Public/RNDeviceInfo" "${PODS_ROOT}/Headers/Public/RNFastImage" "${PODS_ROOT}/Headers/Public/RNFirebase" "${PODS_ROOT}/Headers/Public/RNGestureHandler" "${PODS_ROOT}/Headers/Public/RNImageCropPicker" "${PODS_ROOT}/Headers/Public/RNLocalize" "${PODS_ROOT}/Headers/Public/RNReanimated" "${PODS_ROOT}/Headers/Public/RNScreens" "${PODS_ROOT}/Headers/Public/RNUserDefaults" "${PODS_ROOT}/Headers/Public/RNVectorIcons" "${PODS_ROOT}/Headers/Public/RSKImageCropper" "${PODS_ROOT}/Headers/Public/React-Core" "${PODS_ROOT}/Headers/Public/React-RCTBlob" "${PODS_ROOT}/Headers/Public/React-RCTText" "${PODS_ROOT}/Headers/Public/React-cxxreact" "${PODS_ROOT}/Headers/Public/React-jsi" "${PODS_ROOT}/Headers/Public/React-jsiexecutor" "${PODS_ROOT}/Headers/Public/React-jsinspector" "${PODS_ROOT}/Headers/Public/ReactCommon" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SDWebImageWebPCoder" "${PODS_ROOT}/Headers/Public/UMBarCodeScannerInterface" "${PODS_ROOT}/Headers/Public/UMCameraInterface" "${PODS_ROOT}/Headers/Public/UMConstantsInterface" "${PODS_ROOT}/Headers/Public/UMCore" "${PODS_ROOT}/Headers/Public/UMFaceDetectorInterface" "${PODS_ROOT}/Headers/Public/UMFileSystemInterface" "${PODS_ROOT}/Headers/Public/UMFontInterface" "${PODS_ROOT}/Headers/Public/UMImageLoaderInterface" "${PODS_ROOT}/Headers/Public/UMPermissionsInterface" "${PODS_ROOT}/Headers/Public/UMReactNativeAdapter" "${PODS_ROOT}/Headers/Public/UMSensorsInterface" "${PODS_ROOT}/Headers/Public/UMTaskManagerInterface" "${PODS_ROOT}/Headers/Public/Yoga" "${PODS_ROOT}/Headers/Public/glog" "${PODS_ROOT}/Headers/Public/libwebp" "${PODS_ROOT}/Headers/Public/nanopb" "${PODS_ROOT}/Headers/Public/react-native-background-timer" "${PODS_ROOT}/Headers/Public/react-native-document-picker" "${PODS_ROOT}/Headers/Public/react-native-jitsi-meet" "${PODS_ROOT}/Headers/Public/react-native-keyboard-input" "${PODS_ROOT}/Headers/Public/react-native-keyboard-tracking-view" "${PODS_ROOT}/Headers/Public/react-native-notifications" "${PODS_ROOT}/Headers/Public/react-native-orientation-locker" "${PODS_ROOT}/Headers/Public/react-native-slider" "${PODS_ROOT}/Headers/Public/react-native-splash-screen" "${PODS_ROOT}/Headers/Public/react-native-video" "${PODS_ROOT}/Headers/Public/react-native-webview" "${PODS_ROOT}/Headers/Public/rn-extensions-share" "${PODS_ROOT}/Headers/Public/rn-fetch-blob" $(inherited) ${PODS_ROOT}/Firebase/CoreOnly/Sources "$(PODS_ROOT)/Headers/Private/React-Core"
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BugsnagReactNative" "${PODS_CONFIGURATION_BUILD_DIR}/DoubleConversion" "${PODS_CONFIGURATION_BUILD_DIR}/EXAV" "${PODS_CONFIGURATION_BUILD_DIR}/EXAppLoaderProvider" "${PODS_CONFIGURATION_BUILD_DIR}/EXConstants" "${PODS_CONFIGURATION_BUILD_DIR}/EXFileSystem" "${PODS_CONFIGURATION_BUILD_DIR}/EXHaptics" "${PODS_CONFIGURATION_BUILD_DIR}/EXPermissions" "${PODS_CONFIGURATION_BUILD_DIR}/EXWebBrowser" "${PODS_CONFIGURATION_BUILD_DIR}/FBReactNativeSpec" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreDiagnostics" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstanceID" "${PODS_CONFIGURATION_BUILD_DIR}/Folly" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransportCCTSupport" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/QBImagePickerController" "${PODS_CONFIGURATION_BUILD_DIR}/RCTTypeSafety" "${PODS_CONFIGURATION_BUILD_DIR}/RNAudio" "${PODS_CONFIGURATION_BUILD_DIR}/RNDeviceInfo" "${PODS_CONFIGURATION_BUILD_DIR}/RNFastImage" "${PODS_CONFIGURATION_BUILD_DIR}/RNFirebase" "${PODS_CONFIGURATION_BUILD_DIR}/RNGestureHandler" "${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker" "${PODS_CONFIGURATION_BUILD_DIR}/RNLocalize" "${PODS_CONFIGURATION_BUILD_DIR}/RNReanimated" "${PODS_CONFIGURATION_BUILD_DIR}/RNScreens" "${PODS_CONFIGURATION_BUILD_DIR}/RNUserDefaults" "${PODS_CONFIGURATION_BUILD_DIR}/RNVectorIcons" "${PODS_CONFIGURATION_BUILD_DIR}/RSKImageCropper" "${PODS_CONFIGURATION_BUILD_DIR}/React-Core" "${PODS_CONFIGURATION_BUILD_DIR}/React-CoreModules" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTActionSheet" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTAnimation" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTBlob" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTImage" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTLinking" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTNetwork" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTSettings" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTText" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTVibration" "${PODS_CONFIGURATION_BUILD_DIR}/React-cxxreact" "${PODS_CONFIGURATION_BUILD_DIR}/React-jsi" "${PODS_CONFIGURATION_BUILD_DIR}/React-jsiexecutor" "${PODS_CONFIGURATION_BUILD_DIR}/React-jsinspector" "${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder" "${PODS_CONFIGURATION_BUILD_DIR}/UMCore" "${PODS_CONFIGURATION_BUILD_DIR}/UMReactNativeAdapter" "${PODS_CONFIGURATION_BUILD_DIR}/Yoga" "${PODS_CONFIGURATION_BUILD_DIR}/glog" "${PODS_CONFIGURATION_BUILD_DIR}/libwebp" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-background-timer" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-document-picker" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-jitsi-meet" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-keyboard-input" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-keyboard-tracking-view" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-notifications" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-orientation-locker" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-slider" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-splash-screen" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-video" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-webview" "${PODS_CONFIGURATION_BUILD_DIR}/rn-extensions-share" "${PODS_CONFIGURATION_BUILD_DIR}/rn-fetch-blob"
OTHER_LDFLAGS = $(inherited) -ObjC -l"BugsnagReactNative" -l"DoubleConversion" -l"EXAV" -l"EXAppLoaderProvider" -l"EXConstants" -l"EXFileSystem" -l"EXHaptics" -l"EXPermissions" -l"EXWebBrowser" -l"FBReactNativeSpec" -l"FirebaseCore" -l"FirebaseCoreDiagnostics" -l"FirebaseInstanceID" -l"Folly" -l"GoogleDataTransport" -l"GoogleDataTransportCCTSupport" -l"GoogleUtilities" -l"QBImagePickerController" -l"RCTTypeSafety" -l"RNAudio" -l"RNDeviceInfo" -l"RNFastImage" -l"RNFirebase" -l"RNGestureHandler" -l"RNImageCropPicker" -l"RNLocalize" -l"RNReanimated" -l"RNScreens" -l"RNUserDefaults" -l"RNVectorIcons" -l"RSKImageCropper" -l"React-Core" -l"React-CoreModules" -l"React-RCTActionSheet" -l"React-RCTAnimation" -l"React-RCTBlob" -l"React-RCTImage" -l"React-RCTLinking" -l"React-RCTNetwork" -l"React-RCTSettings" -l"React-RCTText" -l"React-RCTVibration" -l"React-cxxreact" -l"React-jsi" -l"React-jsiexecutor" -l"React-jsinspector" -l"ReactCommon" -l"SDWebImage" -l"SDWebImageWebPCoder" -l"UMCore" -l"UMReactNativeAdapter" -l"Yoga" -l"c++" -l"glog" -l"libwebp" -l"nanopb" -l"react-native-background-timer" -l"react-native-document-picker" -l"react-native-jitsi-meet" -l"react-native-keyboard-input" -l"react-native-keyboard-tracking-view" -l"react-native-notifications" -l"react-native-orientation-locker" -l"react-native-slider" -l"react-native-splash-screen" -l"react-native-video" -l"react-native-webview" -l"rn-extensions-share" -l"rn-fetch-blob" -l"sqlite3" -l"stdc++" -l"z" -framework "AVFoundation" -framework "Crashlytics" -framework "FIRAnalyticsConnector" -framework "Fabric" -framework "FirebaseAnalytics" -framework "Foundation" -framework "GoogleAppMeasurement" -framework "ImageIO" -framework "JavaScriptCore" -framework "JitsiMeet" -framework "MessageUI" -framework "Photos" -framework "QuartzCore" -framework "Security" -framework "StoreKit" -framework "SystemConfiguration" -framework "UIKit" -framework "WebRTC"
LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BugsnagReactNative" "${PODS_CONFIGURATION_BUILD_DIR}/DoubleConversion" "${PODS_CONFIGURATION_BUILD_DIR}/EXAV" "${PODS_CONFIGURATION_BUILD_DIR}/EXAppLoaderProvider" "${PODS_CONFIGURATION_BUILD_DIR}/EXConstants" "${PODS_CONFIGURATION_BUILD_DIR}/EXFileSystem" "${PODS_CONFIGURATION_BUILD_DIR}/EXHaptics" "${PODS_CONFIGURATION_BUILD_DIR}/EXPermissions" "${PODS_CONFIGURATION_BUILD_DIR}/EXWebBrowser" "${PODS_CONFIGURATION_BUILD_DIR}/FBReactNativeSpec" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreDiagnostics" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstanceID" "${PODS_CONFIGURATION_BUILD_DIR}/Folly" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransportCCTSupport" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/KeyCommands" "${PODS_CONFIGURATION_BUILD_DIR}/QBImagePickerController" "${PODS_CONFIGURATION_BUILD_DIR}/RCTTypeSafety" "${PODS_CONFIGURATION_BUILD_DIR}/RNAudio" "${PODS_CONFIGURATION_BUILD_DIR}/RNDeviceInfo" "${PODS_CONFIGURATION_BUILD_DIR}/RNFastImage" "${PODS_CONFIGURATION_BUILD_DIR}/RNFirebase" "${PODS_CONFIGURATION_BUILD_DIR}/RNGestureHandler" "${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker" "${PODS_CONFIGURATION_BUILD_DIR}/RNLocalize" "${PODS_CONFIGURATION_BUILD_DIR}/RNReanimated" "${PODS_CONFIGURATION_BUILD_DIR}/RNScreens" "${PODS_CONFIGURATION_BUILD_DIR}/RNUserDefaults" "${PODS_CONFIGURATION_BUILD_DIR}/RNVectorIcons" "${PODS_CONFIGURATION_BUILD_DIR}/RSKImageCropper" "${PODS_CONFIGURATION_BUILD_DIR}/React-Core" "${PODS_CONFIGURATION_BUILD_DIR}/React-CoreModules" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTActionSheet" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTAnimation" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTBlob" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTImage" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTLinking" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTNetwork" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTSettings" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTText" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTVibration" "${PODS_CONFIGURATION_BUILD_DIR}/React-cxxreact" "${PODS_CONFIGURATION_BUILD_DIR}/React-jsi" "${PODS_CONFIGURATION_BUILD_DIR}/React-jsiexecutor" "${PODS_CONFIGURATION_BUILD_DIR}/React-jsinspector" "${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder" "${PODS_CONFIGURATION_BUILD_DIR}/UMCore" "${PODS_CONFIGURATION_BUILD_DIR}/UMReactNativeAdapter" "${PODS_CONFIGURATION_BUILD_DIR}/Yoga" "${PODS_CONFIGURATION_BUILD_DIR}/glog" "${PODS_CONFIGURATION_BUILD_DIR}/libwebp" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-background-timer" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-document-picker" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-jitsi-meet" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-keyboard-input" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-keyboard-tracking-view" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-notifications" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-orientation-locker" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-slider" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-splash-screen" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-video" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-webview" "${PODS_CONFIGURATION_BUILD_DIR}/rn-extensions-share" "${PODS_CONFIGURATION_BUILD_DIR}/rn-fetch-blob"
OTHER_LDFLAGS = $(inherited) -ObjC -l"BugsnagReactNative" -l"DoubleConversion" -l"EXAV" -l"EXAppLoaderProvider" -l"EXConstants" -l"EXFileSystem" -l"EXHaptics" -l"EXPermissions" -l"EXWebBrowser" -l"FBReactNativeSpec" -l"FirebaseCore" -l"FirebaseCoreDiagnostics" -l"FirebaseInstanceID" -l"Folly" -l"GoogleDataTransport" -l"GoogleDataTransportCCTSupport" -l"GoogleUtilities" -l"KeyCommands" -l"QBImagePickerController" -l"RCTTypeSafety" -l"RNAudio" -l"RNDeviceInfo" -l"RNFastImage" -l"RNFirebase" -l"RNGestureHandler" -l"RNImageCropPicker" -l"RNLocalize" -l"RNReanimated" -l"RNScreens" -l"RNUserDefaults" -l"RNVectorIcons" -l"RSKImageCropper" -l"React-Core" -l"React-CoreModules" -l"React-RCTActionSheet" -l"React-RCTAnimation" -l"React-RCTBlob" -l"React-RCTImage" -l"React-RCTLinking" -l"React-RCTNetwork" -l"React-RCTSettings" -l"React-RCTText" -l"React-RCTVibration" -l"React-cxxreact" -l"React-jsi" -l"React-jsiexecutor" -l"React-jsinspector" -l"ReactCommon" -l"SDWebImage" -l"SDWebImageWebPCoder" -l"UMCore" -l"UMReactNativeAdapter" -l"Yoga" -l"c++" -l"glog" -l"libwebp" -l"nanopb" -l"react-native-background-timer" -l"react-native-document-picker" -l"react-native-jitsi-meet" -l"react-native-keyboard-input" -l"react-native-keyboard-tracking-view" -l"react-native-notifications" -l"react-native-orientation-locker" -l"react-native-slider" -l"react-native-splash-screen" -l"react-native-video" -l"react-native-webview" -l"rn-extensions-share" -l"rn-fetch-blob" -l"sqlite3" -l"stdc++" -l"z" -framework "AVFoundation" -framework "Crashlytics" -framework "FIRAnalyticsConnector" -framework "Fabric" -framework "FirebaseAnalytics" -framework "Foundation" -framework "GoogleAppMeasurement" -framework "ImageIO" -framework "JavaScriptCore" -framework "JitsiMeet" -framework "MessageUI" -framework "Photos" -framework "QuartzCore" -framework "Security" -framework "StoreKit" -framework "SystemConfiguration" -framework "UIKit" -framework "WebRTC"
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.

View File

@ -1,9 +1,9 @@
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Crashlytics/iOS" "${PODS_ROOT}/Fabric/iOS" "${PODS_ROOT}/FirebaseAnalytics/Frameworks" "${PODS_ROOT}/GoogleAppMeasurement/Frameworks" "${PODS_ROOT}/JitsiMeetSDK/Frameworks"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) SD_WEBP=1 $(inherited) PB_FIELD_32BIT=1 PB_NO_PACKED_STRUCTS=1 PB_ENABLE_MALLOC=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/BugsnagReactNative" "${PODS_ROOT}/Headers/Public/DoubleConversion" "${PODS_ROOT}/Headers/Public/EXAV" "${PODS_ROOT}/Headers/Public/EXAppLoaderProvider" "${PODS_ROOT}/Headers/Public/EXConstants" "${PODS_ROOT}/Headers/Public/EXFileSystem" "${PODS_ROOT}/Headers/Public/EXHaptics" "${PODS_ROOT}/Headers/Public/EXPermissions" "${PODS_ROOT}/Headers/Public/EXWebBrowser" "${PODS_ROOT}/Headers/Public/FBLazyVector" "${PODS_ROOT}/Headers/Public/FBReactNativeSpec" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseCoreDiagnostics" "${PODS_ROOT}/Headers/Public/FirebaseCoreDiagnosticsInterop" "${PODS_ROOT}/Headers/Public/FirebaseInstanceID" "${PODS_ROOT}/Headers/Public/GoogleDataTransport" "${PODS_ROOT}/Headers/Public/GoogleDataTransportCCTSupport" "${PODS_ROOT}/Headers/Public/GoogleUtilities" "${PODS_ROOT}/Headers/Public/QBImagePickerController" "${PODS_ROOT}/Headers/Public/RCTRequired" "${PODS_ROOT}/Headers/Public/RCTTypeSafety" "${PODS_ROOT}/Headers/Public/RNAudio" "${PODS_ROOT}/Headers/Public/RNDeviceInfo" "${PODS_ROOT}/Headers/Public/RNFastImage" "${PODS_ROOT}/Headers/Public/RNFirebase" "${PODS_ROOT}/Headers/Public/RNGestureHandler" "${PODS_ROOT}/Headers/Public/RNImageCropPicker" "${PODS_ROOT}/Headers/Public/RNLocalize" "${PODS_ROOT}/Headers/Public/RNReanimated" "${PODS_ROOT}/Headers/Public/RNScreens" "${PODS_ROOT}/Headers/Public/RNUserDefaults" "${PODS_ROOT}/Headers/Public/RNVectorIcons" "${PODS_ROOT}/Headers/Public/RSKImageCropper" "${PODS_ROOT}/Headers/Public/React-Core" "${PODS_ROOT}/Headers/Public/React-RCTBlob" "${PODS_ROOT}/Headers/Public/React-RCTText" "${PODS_ROOT}/Headers/Public/React-cxxreact" "${PODS_ROOT}/Headers/Public/React-jsi" "${PODS_ROOT}/Headers/Public/React-jsiexecutor" "${PODS_ROOT}/Headers/Public/React-jsinspector" "${PODS_ROOT}/Headers/Public/ReactCommon" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SDWebImageWebPCoder" "${PODS_ROOT}/Headers/Public/UMBarCodeScannerInterface" "${PODS_ROOT}/Headers/Public/UMCameraInterface" "${PODS_ROOT}/Headers/Public/UMConstantsInterface" "${PODS_ROOT}/Headers/Public/UMCore" "${PODS_ROOT}/Headers/Public/UMFaceDetectorInterface" "${PODS_ROOT}/Headers/Public/UMFileSystemInterface" "${PODS_ROOT}/Headers/Public/UMFontInterface" "${PODS_ROOT}/Headers/Public/UMImageLoaderInterface" "${PODS_ROOT}/Headers/Public/UMPermissionsInterface" "${PODS_ROOT}/Headers/Public/UMReactNativeAdapter" "${PODS_ROOT}/Headers/Public/UMSensorsInterface" "${PODS_ROOT}/Headers/Public/UMTaskManagerInterface" "${PODS_ROOT}/Headers/Public/Yoga" "${PODS_ROOT}/Headers/Public/glog" "${PODS_ROOT}/Headers/Public/libwebp" "${PODS_ROOT}/Headers/Public/nanopb" "${PODS_ROOT}/Headers/Public/react-native-background-timer" "${PODS_ROOT}/Headers/Public/react-native-document-picker" "${PODS_ROOT}/Headers/Public/react-native-jitsi-meet" "${PODS_ROOT}/Headers/Public/react-native-keyboard-input" "${PODS_ROOT}/Headers/Public/react-native-keyboard-tracking-view" "${PODS_ROOT}/Headers/Public/react-native-notifications" "${PODS_ROOT}/Headers/Public/react-native-orientation-locker" "${PODS_ROOT}/Headers/Public/react-native-slider" "${PODS_ROOT}/Headers/Public/react-native-splash-screen" "${PODS_ROOT}/Headers/Public/react-native-video" "${PODS_ROOT}/Headers/Public/react-native-webview" "${PODS_ROOT}/Headers/Public/rn-extensions-share" "${PODS_ROOT}/Headers/Public/rn-fetch-blob" $(inherited) ${PODS_ROOT}/Firebase/CoreOnly/Sources "$(PODS_ROOT)/Headers/Private/React-Core"
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/BugsnagReactNative" "${PODS_ROOT}/Headers/Public/DoubleConversion" "${PODS_ROOT}/Headers/Public/EXAV" "${PODS_ROOT}/Headers/Public/EXAppLoaderProvider" "${PODS_ROOT}/Headers/Public/EXConstants" "${PODS_ROOT}/Headers/Public/EXFileSystem" "${PODS_ROOT}/Headers/Public/EXHaptics" "${PODS_ROOT}/Headers/Public/EXPermissions" "${PODS_ROOT}/Headers/Public/EXWebBrowser" "${PODS_ROOT}/Headers/Public/FBLazyVector" "${PODS_ROOT}/Headers/Public/FBReactNativeSpec" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseCoreDiagnostics" "${PODS_ROOT}/Headers/Public/FirebaseCoreDiagnosticsInterop" "${PODS_ROOT}/Headers/Public/FirebaseInstanceID" "${PODS_ROOT}/Headers/Public/GoogleDataTransport" "${PODS_ROOT}/Headers/Public/GoogleDataTransportCCTSupport" "${PODS_ROOT}/Headers/Public/GoogleUtilities" "${PODS_ROOT}/Headers/Public/KeyCommands" "${PODS_ROOT}/Headers/Public/QBImagePickerController" "${PODS_ROOT}/Headers/Public/RCTRequired" "${PODS_ROOT}/Headers/Public/RCTTypeSafety" "${PODS_ROOT}/Headers/Public/RNAudio" "${PODS_ROOT}/Headers/Public/RNDeviceInfo" "${PODS_ROOT}/Headers/Public/RNFastImage" "${PODS_ROOT}/Headers/Public/RNFirebase" "${PODS_ROOT}/Headers/Public/RNGestureHandler" "${PODS_ROOT}/Headers/Public/RNImageCropPicker" "${PODS_ROOT}/Headers/Public/RNLocalize" "${PODS_ROOT}/Headers/Public/RNReanimated" "${PODS_ROOT}/Headers/Public/RNScreens" "${PODS_ROOT}/Headers/Public/RNUserDefaults" "${PODS_ROOT}/Headers/Public/RNVectorIcons" "${PODS_ROOT}/Headers/Public/RSKImageCropper" "${PODS_ROOT}/Headers/Public/React-Core" "${PODS_ROOT}/Headers/Public/React-RCTBlob" "${PODS_ROOT}/Headers/Public/React-RCTText" "${PODS_ROOT}/Headers/Public/React-cxxreact" "${PODS_ROOT}/Headers/Public/React-jsi" "${PODS_ROOT}/Headers/Public/React-jsiexecutor" "${PODS_ROOT}/Headers/Public/React-jsinspector" "${PODS_ROOT}/Headers/Public/ReactCommon" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SDWebImageWebPCoder" "${PODS_ROOT}/Headers/Public/UMBarCodeScannerInterface" "${PODS_ROOT}/Headers/Public/UMCameraInterface" "${PODS_ROOT}/Headers/Public/UMConstantsInterface" "${PODS_ROOT}/Headers/Public/UMCore" "${PODS_ROOT}/Headers/Public/UMFaceDetectorInterface" "${PODS_ROOT}/Headers/Public/UMFileSystemInterface" "${PODS_ROOT}/Headers/Public/UMFontInterface" "${PODS_ROOT}/Headers/Public/UMImageLoaderInterface" "${PODS_ROOT}/Headers/Public/UMPermissionsInterface" "${PODS_ROOT}/Headers/Public/UMReactNativeAdapter" "${PODS_ROOT}/Headers/Public/UMSensorsInterface" "${PODS_ROOT}/Headers/Public/UMTaskManagerInterface" "${PODS_ROOT}/Headers/Public/Yoga" "${PODS_ROOT}/Headers/Public/glog" "${PODS_ROOT}/Headers/Public/libwebp" "${PODS_ROOT}/Headers/Public/nanopb" "${PODS_ROOT}/Headers/Public/react-native-background-timer" "${PODS_ROOT}/Headers/Public/react-native-document-picker" "${PODS_ROOT}/Headers/Public/react-native-jitsi-meet" "${PODS_ROOT}/Headers/Public/react-native-keyboard-input" "${PODS_ROOT}/Headers/Public/react-native-keyboard-tracking-view" "${PODS_ROOT}/Headers/Public/react-native-notifications" "${PODS_ROOT}/Headers/Public/react-native-orientation-locker" "${PODS_ROOT}/Headers/Public/react-native-slider" "${PODS_ROOT}/Headers/Public/react-native-splash-screen" "${PODS_ROOT}/Headers/Public/react-native-video" "${PODS_ROOT}/Headers/Public/react-native-webview" "${PODS_ROOT}/Headers/Public/rn-extensions-share" "${PODS_ROOT}/Headers/Public/rn-fetch-blob" $(inherited) ${PODS_ROOT}/Firebase/CoreOnly/Sources "$(PODS_ROOT)/Headers/Private/React-Core"
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BugsnagReactNative" "${PODS_CONFIGURATION_BUILD_DIR}/DoubleConversion" "${PODS_CONFIGURATION_BUILD_DIR}/EXAV" "${PODS_CONFIGURATION_BUILD_DIR}/EXAppLoaderProvider" "${PODS_CONFIGURATION_BUILD_DIR}/EXConstants" "${PODS_CONFIGURATION_BUILD_DIR}/EXFileSystem" "${PODS_CONFIGURATION_BUILD_DIR}/EXHaptics" "${PODS_CONFIGURATION_BUILD_DIR}/EXPermissions" "${PODS_CONFIGURATION_BUILD_DIR}/EXWebBrowser" "${PODS_CONFIGURATION_BUILD_DIR}/FBReactNativeSpec" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreDiagnostics" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstanceID" "${PODS_CONFIGURATION_BUILD_DIR}/Folly" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransportCCTSupport" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/QBImagePickerController" "${PODS_CONFIGURATION_BUILD_DIR}/RCTTypeSafety" "${PODS_CONFIGURATION_BUILD_DIR}/RNAudio" "${PODS_CONFIGURATION_BUILD_DIR}/RNDeviceInfo" "${PODS_CONFIGURATION_BUILD_DIR}/RNFastImage" "${PODS_CONFIGURATION_BUILD_DIR}/RNFirebase" "${PODS_CONFIGURATION_BUILD_DIR}/RNGestureHandler" "${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker" "${PODS_CONFIGURATION_BUILD_DIR}/RNLocalize" "${PODS_CONFIGURATION_BUILD_DIR}/RNReanimated" "${PODS_CONFIGURATION_BUILD_DIR}/RNScreens" "${PODS_CONFIGURATION_BUILD_DIR}/RNUserDefaults" "${PODS_CONFIGURATION_BUILD_DIR}/RNVectorIcons" "${PODS_CONFIGURATION_BUILD_DIR}/RSKImageCropper" "${PODS_CONFIGURATION_BUILD_DIR}/React-Core" "${PODS_CONFIGURATION_BUILD_DIR}/React-CoreModules" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTActionSheet" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTAnimation" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTBlob" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTImage" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTLinking" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTNetwork" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTSettings" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTText" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTVibration" "${PODS_CONFIGURATION_BUILD_DIR}/React-cxxreact" "${PODS_CONFIGURATION_BUILD_DIR}/React-jsi" "${PODS_CONFIGURATION_BUILD_DIR}/React-jsiexecutor" "${PODS_CONFIGURATION_BUILD_DIR}/React-jsinspector" "${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder" "${PODS_CONFIGURATION_BUILD_DIR}/UMCore" "${PODS_CONFIGURATION_BUILD_DIR}/UMReactNativeAdapter" "${PODS_CONFIGURATION_BUILD_DIR}/Yoga" "${PODS_CONFIGURATION_BUILD_DIR}/glog" "${PODS_CONFIGURATION_BUILD_DIR}/libwebp" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-background-timer" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-document-picker" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-jitsi-meet" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-keyboard-input" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-keyboard-tracking-view" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-notifications" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-orientation-locker" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-slider" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-splash-screen" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-video" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-webview" "${PODS_CONFIGURATION_BUILD_DIR}/rn-extensions-share" "${PODS_CONFIGURATION_BUILD_DIR}/rn-fetch-blob"
OTHER_LDFLAGS = $(inherited) -ObjC -l"BugsnagReactNative" -l"DoubleConversion" -l"EXAV" -l"EXAppLoaderProvider" -l"EXConstants" -l"EXFileSystem" -l"EXHaptics" -l"EXPermissions" -l"EXWebBrowser" -l"FBReactNativeSpec" -l"FirebaseCore" -l"FirebaseCoreDiagnostics" -l"FirebaseInstanceID" -l"Folly" -l"GoogleDataTransport" -l"GoogleDataTransportCCTSupport" -l"GoogleUtilities" -l"QBImagePickerController" -l"RCTTypeSafety" -l"RNAudio" -l"RNDeviceInfo" -l"RNFastImage" -l"RNFirebase" -l"RNGestureHandler" -l"RNImageCropPicker" -l"RNLocalize" -l"RNReanimated" -l"RNScreens" -l"RNUserDefaults" -l"RNVectorIcons" -l"RSKImageCropper" -l"React-Core" -l"React-CoreModules" -l"React-RCTActionSheet" -l"React-RCTAnimation" -l"React-RCTBlob" -l"React-RCTImage" -l"React-RCTLinking" -l"React-RCTNetwork" -l"React-RCTSettings" -l"React-RCTText" -l"React-RCTVibration" -l"React-cxxreact" -l"React-jsi" -l"React-jsiexecutor" -l"React-jsinspector" -l"ReactCommon" -l"SDWebImage" -l"SDWebImageWebPCoder" -l"UMCore" -l"UMReactNativeAdapter" -l"Yoga" -l"c++" -l"glog" -l"libwebp" -l"nanopb" -l"react-native-background-timer" -l"react-native-document-picker" -l"react-native-jitsi-meet" -l"react-native-keyboard-input" -l"react-native-keyboard-tracking-view" -l"react-native-notifications" -l"react-native-orientation-locker" -l"react-native-slider" -l"react-native-splash-screen" -l"react-native-video" -l"react-native-webview" -l"rn-extensions-share" -l"rn-fetch-blob" -l"sqlite3" -l"stdc++" -l"z" -framework "AVFoundation" -framework "Crashlytics" -framework "FIRAnalyticsConnector" -framework "Fabric" -framework "FirebaseAnalytics" -framework "Foundation" -framework "GoogleAppMeasurement" -framework "ImageIO" -framework "JavaScriptCore" -framework "JitsiMeet" -framework "MessageUI" -framework "Photos" -framework "QuartzCore" -framework "Security" -framework "StoreKit" -framework "SystemConfiguration" -framework "UIKit" -framework "WebRTC"
LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BugsnagReactNative" "${PODS_CONFIGURATION_BUILD_DIR}/DoubleConversion" "${PODS_CONFIGURATION_BUILD_DIR}/EXAV" "${PODS_CONFIGURATION_BUILD_DIR}/EXAppLoaderProvider" "${PODS_CONFIGURATION_BUILD_DIR}/EXConstants" "${PODS_CONFIGURATION_BUILD_DIR}/EXFileSystem" "${PODS_CONFIGURATION_BUILD_DIR}/EXHaptics" "${PODS_CONFIGURATION_BUILD_DIR}/EXPermissions" "${PODS_CONFIGURATION_BUILD_DIR}/EXWebBrowser" "${PODS_CONFIGURATION_BUILD_DIR}/FBReactNativeSpec" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreDiagnostics" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstanceID" "${PODS_CONFIGURATION_BUILD_DIR}/Folly" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransportCCTSupport" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/KeyCommands" "${PODS_CONFIGURATION_BUILD_DIR}/QBImagePickerController" "${PODS_CONFIGURATION_BUILD_DIR}/RCTTypeSafety" "${PODS_CONFIGURATION_BUILD_DIR}/RNAudio" "${PODS_CONFIGURATION_BUILD_DIR}/RNDeviceInfo" "${PODS_CONFIGURATION_BUILD_DIR}/RNFastImage" "${PODS_CONFIGURATION_BUILD_DIR}/RNFirebase" "${PODS_CONFIGURATION_BUILD_DIR}/RNGestureHandler" "${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker" "${PODS_CONFIGURATION_BUILD_DIR}/RNLocalize" "${PODS_CONFIGURATION_BUILD_DIR}/RNReanimated" "${PODS_CONFIGURATION_BUILD_DIR}/RNScreens" "${PODS_CONFIGURATION_BUILD_DIR}/RNUserDefaults" "${PODS_CONFIGURATION_BUILD_DIR}/RNVectorIcons" "${PODS_CONFIGURATION_BUILD_DIR}/RSKImageCropper" "${PODS_CONFIGURATION_BUILD_DIR}/React-Core" "${PODS_CONFIGURATION_BUILD_DIR}/React-CoreModules" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTActionSheet" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTAnimation" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTBlob" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTImage" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTLinking" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTNetwork" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTSettings" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTText" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTVibration" "${PODS_CONFIGURATION_BUILD_DIR}/React-cxxreact" "${PODS_CONFIGURATION_BUILD_DIR}/React-jsi" "${PODS_CONFIGURATION_BUILD_DIR}/React-jsiexecutor" "${PODS_CONFIGURATION_BUILD_DIR}/React-jsinspector" "${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder" "${PODS_CONFIGURATION_BUILD_DIR}/UMCore" "${PODS_CONFIGURATION_BUILD_DIR}/UMReactNativeAdapter" "${PODS_CONFIGURATION_BUILD_DIR}/Yoga" "${PODS_CONFIGURATION_BUILD_DIR}/glog" "${PODS_CONFIGURATION_BUILD_DIR}/libwebp" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-background-timer" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-document-picker" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-jitsi-meet" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-keyboard-input" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-keyboard-tracking-view" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-notifications" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-orientation-locker" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-slider" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-splash-screen" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-video" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-webview" "${PODS_CONFIGURATION_BUILD_DIR}/rn-extensions-share" "${PODS_CONFIGURATION_BUILD_DIR}/rn-fetch-blob"
OTHER_LDFLAGS = $(inherited) -ObjC -l"BugsnagReactNative" -l"DoubleConversion" -l"EXAV" -l"EXAppLoaderProvider" -l"EXConstants" -l"EXFileSystem" -l"EXHaptics" -l"EXPermissions" -l"EXWebBrowser" -l"FBReactNativeSpec" -l"FirebaseCore" -l"FirebaseCoreDiagnostics" -l"FirebaseInstanceID" -l"Folly" -l"GoogleDataTransport" -l"GoogleDataTransportCCTSupport" -l"GoogleUtilities" -l"KeyCommands" -l"QBImagePickerController" -l"RCTTypeSafety" -l"RNAudio" -l"RNDeviceInfo" -l"RNFastImage" -l"RNFirebase" -l"RNGestureHandler" -l"RNImageCropPicker" -l"RNLocalize" -l"RNReanimated" -l"RNScreens" -l"RNUserDefaults" -l"RNVectorIcons" -l"RSKImageCropper" -l"React-Core" -l"React-CoreModules" -l"React-RCTActionSheet" -l"React-RCTAnimation" -l"React-RCTBlob" -l"React-RCTImage" -l"React-RCTLinking" -l"React-RCTNetwork" -l"React-RCTSettings" -l"React-RCTText" -l"React-RCTVibration" -l"React-cxxreact" -l"React-jsi" -l"React-jsiexecutor" -l"React-jsinspector" -l"ReactCommon" -l"SDWebImage" -l"SDWebImageWebPCoder" -l"UMCore" -l"UMReactNativeAdapter" -l"Yoga" -l"c++" -l"glog" -l"libwebp" -l"nanopb" -l"react-native-background-timer" -l"react-native-document-picker" -l"react-native-jitsi-meet" -l"react-native-keyboard-input" -l"react-native-keyboard-tracking-view" -l"react-native-notifications" -l"react-native-orientation-locker" -l"react-native-slider" -l"react-native-splash-screen" -l"react-native-video" -l"react-native-webview" -l"rn-extensions-share" -l"rn-fetch-blob" -l"sqlite3" -l"stdc++" -l"z" -framework "AVFoundation" -framework "Crashlytics" -framework "FIRAnalyticsConnector" -framework "Fabric" -framework "FirebaseAnalytics" -framework "Foundation" -framework "GoogleAppMeasurement" -framework "ImageIO" -framework "JavaScriptCore" -framework "JitsiMeet" -framework "MessageUI" -framework "Photos" -framework "QuartzCore" -framework "Security" -framework "StoreKit" -framework "SystemConfiguration" -framework "UIKit" -framework "WebRTC"
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.

View File

@ -1,9 +1,9 @@
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Crashlytics/iOS" "${PODS_ROOT}/Fabric/iOS" "${PODS_ROOT}/FirebaseAnalytics/Frameworks" "${PODS_ROOT}/GoogleAppMeasurement/Frameworks" "${PODS_ROOT}/JitsiMeetSDK/Frameworks"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) SD_WEBP=1 $(inherited) PB_FIELD_32BIT=1 PB_NO_PACKED_STRUCTS=1 PB_ENABLE_MALLOC=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/BugsnagReactNative" "${PODS_ROOT}/Headers/Public/DoubleConversion" "${PODS_ROOT}/Headers/Public/EXAV" "${PODS_ROOT}/Headers/Public/EXAppLoaderProvider" "${PODS_ROOT}/Headers/Public/EXConstants" "${PODS_ROOT}/Headers/Public/EXFileSystem" "${PODS_ROOT}/Headers/Public/EXHaptics" "${PODS_ROOT}/Headers/Public/EXPermissions" "${PODS_ROOT}/Headers/Public/EXWebBrowser" "${PODS_ROOT}/Headers/Public/FBLazyVector" "${PODS_ROOT}/Headers/Public/FBReactNativeSpec" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseCoreDiagnostics" "${PODS_ROOT}/Headers/Public/FirebaseCoreDiagnosticsInterop" "${PODS_ROOT}/Headers/Public/FirebaseInstanceID" "${PODS_ROOT}/Headers/Public/GoogleDataTransport" "${PODS_ROOT}/Headers/Public/GoogleDataTransportCCTSupport" "${PODS_ROOT}/Headers/Public/GoogleUtilities" "${PODS_ROOT}/Headers/Public/QBImagePickerController" "${PODS_ROOT}/Headers/Public/RCTRequired" "${PODS_ROOT}/Headers/Public/RCTTypeSafety" "${PODS_ROOT}/Headers/Public/RNAudio" "${PODS_ROOT}/Headers/Public/RNDeviceInfo" "${PODS_ROOT}/Headers/Public/RNFastImage" "${PODS_ROOT}/Headers/Public/RNFirebase" "${PODS_ROOT}/Headers/Public/RNGestureHandler" "${PODS_ROOT}/Headers/Public/RNImageCropPicker" "${PODS_ROOT}/Headers/Public/RNLocalize" "${PODS_ROOT}/Headers/Public/RNReanimated" "${PODS_ROOT}/Headers/Public/RNScreens" "${PODS_ROOT}/Headers/Public/RNUserDefaults" "${PODS_ROOT}/Headers/Public/RNVectorIcons" "${PODS_ROOT}/Headers/Public/RSKImageCropper" "${PODS_ROOT}/Headers/Public/React-Core" "${PODS_ROOT}/Headers/Public/React-RCTBlob" "${PODS_ROOT}/Headers/Public/React-RCTText" "${PODS_ROOT}/Headers/Public/React-cxxreact" "${PODS_ROOT}/Headers/Public/React-jsi" "${PODS_ROOT}/Headers/Public/React-jsiexecutor" "${PODS_ROOT}/Headers/Public/React-jsinspector" "${PODS_ROOT}/Headers/Public/ReactCommon" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SDWebImageWebPCoder" "${PODS_ROOT}/Headers/Public/UMBarCodeScannerInterface" "${PODS_ROOT}/Headers/Public/UMCameraInterface" "${PODS_ROOT}/Headers/Public/UMConstantsInterface" "${PODS_ROOT}/Headers/Public/UMCore" "${PODS_ROOT}/Headers/Public/UMFaceDetectorInterface" "${PODS_ROOT}/Headers/Public/UMFileSystemInterface" "${PODS_ROOT}/Headers/Public/UMFontInterface" "${PODS_ROOT}/Headers/Public/UMImageLoaderInterface" "${PODS_ROOT}/Headers/Public/UMPermissionsInterface" "${PODS_ROOT}/Headers/Public/UMReactNativeAdapter" "${PODS_ROOT}/Headers/Public/UMSensorsInterface" "${PODS_ROOT}/Headers/Public/UMTaskManagerInterface" "${PODS_ROOT}/Headers/Public/Yoga" "${PODS_ROOT}/Headers/Public/glog" "${PODS_ROOT}/Headers/Public/libwebp" "${PODS_ROOT}/Headers/Public/nanopb" "${PODS_ROOT}/Headers/Public/react-native-background-timer" "${PODS_ROOT}/Headers/Public/react-native-document-picker" "${PODS_ROOT}/Headers/Public/react-native-jitsi-meet" "${PODS_ROOT}/Headers/Public/react-native-keyboard-input" "${PODS_ROOT}/Headers/Public/react-native-keyboard-tracking-view" "${PODS_ROOT}/Headers/Public/react-native-notifications" "${PODS_ROOT}/Headers/Public/react-native-orientation-locker" "${PODS_ROOT}/Headers/Public/react-native-slider" "${PODS_ROOT}/Headers/Public/react-native-splash-screen" "${PODS_ROOT}/Headers/Public/react-native-video" "${PODS_ROOT}/Headers/Public/react-native-webview" "${PODS_ROOT}/Headers/Public/rn-extensions-share" "${PODS_ROOT}/Headers/Public/rn-fetch-blob" $(inherited) ${PODS_ROOT}/Firebase/CoreOnly/Sources "$(PODS_ROOT)/Headers/Private/React-Core"
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/BugsnagReactNative" "${PODS_ROOT}/Headers/Public/DoubleConversion" "${PODS_ROOT}/Headers/Public/EXAV" "${PODS_ROOT}/Headers/Public/EXAppLoaderProvider" "${PODS_ROOT}/Headers/Public/EXConstants" "${PODS_ROOT}/Headers/Public/EXFileSystem" "${PODS_ROOT}/Headers/Public/EXHaptics" "${PODS_ROOT}/Headers/Public/EXPermissions" "${PODS_ROOT}/Headers/Public/EXWebBrowser" "${PODS_ROOT}/Headers/Public/FBLazyVector" "${PODS_ROOT}/Headers/Public/FBReactNativeSpec" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseCoreDiagnostics" "${PODS_ROOT}/Headers/Public/FirebaseCoreDiagnosticsInterop" "${PODS_ROOT}/Headers/Public/FirebaseInstanceID" "${PODS_ROOT}/Headers/Public/GoogleDataTransport" "${PODS_ROOT}/Headers/Public/GoogleDataTransportCCTSupport" "${PODS_ROOT}/Headers/Public/GoogleUtilities" "${PODS_ROOT}/Headers/Public/KeyCommands" "${PODS_ROOT}/Headers/Public/QBImagePickerController" "${PODS_ROOT}/Headers/Public/RCTRequired" "${PODS_ROOT}/Headers/Public/RCTTypeSafety" "${PODS_ROOT}/Headers/Public/RNAudio" "${PODS_ROOT}/Headers/Public/RNDeviceInfo" "${PODS_ROOT}/Headers/Public/RNFastImage" "${PODS_ROOT}/Headers/Public/RNFirebase" "${PODS_ROOT}/Headers/Public/RNGestureHandler" "${PODS_ROOT}/Headers/Public/RNImageCropPicker" "${PODS_ROOT}/Headers/Public/RNLocalize" "${PODS_ROOT}/Headers/Public/RNReanimated" "${PODS_ROOT}/Headers/Public/RNScreens" "${PODS_ROOT}/Headers/Public/RNUserDefaults" "${PODS_ROOT}/Headers/Public/RNVectorIcons" "${PODS_ROOT}/Headers/Public/RSKImageCropper" "${PODS_ROOT}/Headers/Public/React-Core" "${PODS_ROOT}/Headers/Public/React-RCTBlob" "${PODS_ROOT}/Headers/Public/React-RCTText" "${PODS_ROOT}/Headers/Public/React-cxxreact" "${PODS_ROOT}/Headers/Public/React-jsi" "${PODS_ROOT}/Headers/Public/React-jsiexecutor" "${PODS_ROOT}/Headers/Public/React-jsinspector" "${PODS_ROOT}/Headers/Public/ReactCommon" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SDWebImageWebPCoder" "${PODS_ROOT}/Headers/Public/UMBarCodeScannerInterface" "${PODS_ROOT}/Headers/Public/UMCameraInterface" "${PODS_ROOT}/Headers/Public/UMConstantsInterface" "${PODS_ROOT}/Headers/Public/UMCore" "${PODS_ROOT}/Headers/Public/UMFaceDetectorInterface" "${PODS_ROOT}/Headers/Public/UMFileSystemInterface" "${PODS_ROOT}/Headers/Public/UMFontInterface" "${PODS_ROOT}/Headers/Public/UMImageLoaderInterface" "${PODS_ROOT}/Headers/Public/UMPermissionsInterface" "${PODS_ROOT}/Headers/Public/UMReactNativeAdapter" "${PODS_ROOT}/Headers/Public/UMSensorsInterface" "${PODS_ROOT}/Headers/Public/UMTaskManagerInterface" "${PODS_ROOT}/Headers/Public/Yoga" "${PODS_ROOT}/Headers/Public/glog" "${PODS_ROOT}/Headers/Public/libwebp" "${PODS_ROOT}/Headers/Public/nanopb" "${PODS_ROOT}/Headers/Public/react-native-background-timer" "${PODS_ROOT}/Headers/Public/react-native-document-picker" "${PODS_ROOT}/Headers/Public/react-native-jitsi-meet" "${PODS_ROOT}/Headers/Public/react-native-keyboard-input" "${PODS_ROOT}/Headers/Public/react-native-keyboard-tracking-view" "${PODS_ROOT}/Headers/Public/react-native-notifications" "${PODS_ROOT}/Headers/Public/react-native-orientation-locker" "${PODS_ROOT}/Headers/Public/react-native-slider" "${PODS_ROOT}/Headers/Public/react-native-splash-screen" "${PODS_ROOT}/Headers/Public/react-native-video" "${PODS_ROOT}/Headers/Public/react-native-webview" "${PODS_ROOT}/Headers/Public/rn-extensions-share" "${PODS_ROOT}/Headers/Public/rn-fetch-blob" $(inherited) ${PODS_ROOT}/Firebase/CoreOnly/Sources "$(PODS_ROOT)/Headers/Private/React-Core"
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' '@executable_path/../../Frameworks'
LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BugsnagReactNative" "${PODS_CONFIGURATION_BUILD_DIR}/DoubleConversion" "${PODS_CONFIGURATION_BUILD_DIR}/FBReactNativeSpec" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreDiagnostics" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstanceID" "${PODS_CONFIGURATION_BUILD_DIR}/Folly" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransportCCTSupport" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/QBImagePickerController" "${PODS_CONFIGURATION_BUILD_DIR}/RCTTypeSafety" "${PODS_CONFIGURATION_BUILD_DIR}/RNAudio" "${PODS_CONFIGURATION_BUILD_DIR}/RNDeviceInfo" "${PODS_CONFIGURATION_BUILD_DIR}/RNFastImage" "${PODS_CONFIGURATION_BUILD_DIR}/RNFirebase" "${PODS_CONFIGURATION_BUILD_DIR}/RNGestureHandler" "${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker" "${PODS_CONFIGURATION_BUILD_DIR}/RNLocalize" "${PODS_CONFIGURATION_BUILD_DIR}/RNReanimated" "${PODS_CONFIGURATION_BUILD_DIR}/RNScreens" "${PODS_CONFIGURATION_BUILD_DIR}/RNUserDefaults" "${PODS_CONFIGURATION_BUILD_DIR}/RNVectorIcons" "${PODS_CONFIGURATION_BUILD_DIR}/RSKImageCropper" "${PODS_CONFIGURATION_BUILD_DIR}/React-Core" "${PODS_CONFIGURATION_BUILD_DIR}/React-CoreModules" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTActionSheet" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTAnimation" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTBlob" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTImage" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTLinking" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTNetwork" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTSettings" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTText" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTVibration" "${PODS_CONFIGURATION_BUILD_DIR}/React-cxxreact" "${PODS_CONFIGURATION_BUILD_DIR}/React-jsi" "${PODS_CONFIGURATION_BUILD_DIR}/React-jsiexecutor" "${PODS_CONFIGURATION_BUILD_DIR}/React-jsinspector" "${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder" "${PODS_CONFIGURATION_BUILD_DIR}/Yoga" "${PODS_CONFIGURATION_BUILD_DIR}/glog" "${PODS_CONFIGURATION_BUILD_DIR}/libwebp" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-background-timer" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-document-picker" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-jitsi-meet" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-keyboard-input" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-keyboard-tracking-view" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-notifications" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-orientation-locker" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-slider" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-splash-screen" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-video" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-webview" "${PODS_CONFIGURATION_BUILD_DIR}/rn-extensions-share" "${PODS_CONFIGURATION_BUILD_DIR}/rn-fetch-blob"
OTHER_LDFLAGS = $(inherited) -ObjC -l"BugsnagReactNative" -l"DoubleConversion" -l"FBReactNativeSpec" -l"FirebaseCore" -l"FirebaseCoreDiagnostics" -l"FirebaseInstanceID" -l"Folly" -l"GoogleDataTransport" -l"GoogleDataTransportCCTSupport" -l"GoogleUtilities" -l"QBImagePickerController" -l"RCTTypeSafety" -l"RNAudio" -l"RNDeviceInfo" -l"RNFastImage" -l"RNFirebase" -l"RNGestureHandler" -l"RNImageCropPicker" -l"RNLocalize" -l"RNReanimated" -l"RNScreens" -l"RNUserDefaults" -l"RNVectorIcons" -l"RSKImageCropper" -l"React-Core" -l"React-CoreModules" -l"React-RCTActionSheet" -l"React-RCTAnimation" -l"React-RCTBlob" -l"React-RCTImage" -l"React-RCTLinking" -l"React-RCTNetwork" -l"React-RCTSettings" -l"React-RCTText" -l"React-RCTVibration" -l"React-cxxreact" -l"React-jsi" -l"React-jsiexecutor" -l"React-jsinspector" -l"ReactCommon" -l"SDWebImage" -l"SDWebImageWebPCoder" -l"Yoga" -l"c++" -l"glog" -l"libwebp" -l"nanopb" -l"react-native-background-timer" -l"react-native-document-picker" -l"react-native-jitsi-meet" -l"react-native-keyboard-input" -l"react-native-keyboard-tracking-view" -l"react-native-notifications" -l"react-native-orientation-locker" -l"react-native-slider" -l"react-native-splash-screen" -l"react-native-video" -l"react-native-webview" -l"rn-extensions-share" -l"rn-fetch-blob" -l"sqlite3" -l"stdc++" -l"z" -framework "AVFoundation" -framework "Crashlytics" -framework "FIRAnalyticsConnector" -framework "Fabric" -framework "FirebaseAnalytics" -framework "Foundation" -framework "GoogleAppMeasurement" -framework "ImageIO" -framework "JavaScriptCore" -framework "JitsiMeet" -framework "MessageUI" -framework "Photos" -framework "QuartzCore" -framework "Security" -framework "StoreKit" -framework "SystemConfiguration" -framework "UIKit" -framework "WebRTC"
LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BugsnagReactNative" "${PODS_CONFIGURATION_BUILD_DIR}/DoubleConversion" "${PODS_CONFIGURATION_BUILD_DIR}/FBReactNativeSpec" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreDiagnostics" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstanceID" "${PODS_CONFIGURATION_BUILD_DIR}/Folly" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransportCCTSupport" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/KeyCommands" "${PODS_CONFIGURATION_BUILD_DIR}/QBImagePickerController" "${PODS_CONFIGURATION_BUILD_DIR}/RCTTypeSafety" "${PODS_CONFIGURATION_BUILD_DIR}/RNAudio" "${PODS_CONFIGURATION_BUILD_DIR}/RNDeviceInfo" "${PODS_CONFIGURATION_BUILD_DIR}/RNFastImage" "${PODS_CONFIGURATION_BUILD_DIR}/RNFirebase" "${PODS_CONFIGURATION_BUILD_DIR}/RNGestureHandler" "${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker" "${PODS_CONFIGURATION_BUILD_DIR}/RNLocalize" "${PODS_CONFIGURATION_BUILD_DIR}/RNReanimated" "${PODS_CONFIGURATION_BUILD_DIR}/RNScreens" "${PODS_CONFIGURATION_BUILD_DIR}/RNUserDefaults" "${PODS_CONFIGURATION_BUILD_DIR}/RNVectorIcons" "${PODS_CONFIGURATION_BUILD_DIR}/RSKImageCropper" "${PODS_CONFIGURATION_BUILD_DIR}/React-Core" "${PODS_CONFIGURATION_BUILD_DIR}/React-CoreModules" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTActionSheet" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTAnimation" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTBlob" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTImage" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTLinking" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTNetwork" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTSettings" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTText" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTVibration" "${PODS_CONFIGURATION_BUILD_DIR}/React-cxxreact" "${PODS_CONFIGURATION_BUILD_DIR}/React-jsi" "${PODS_CONFIGURATION_BUILD_DIR}/React-jsiexecutor" "${PODS_CONFIGURATION_BUILD_DIR}/React-jsinspector" "${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder" "${PODS_CONFIGURATION_BUILD_DIR}/Yoga" "${PODS_CONFIGURATION_BUILD_DIR}/glog" "${PODS_CONFIGURATION_BUILD_DIR}/libwebp" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-background-timer" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-document-picker" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-jitsi-meet" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-keyboard-input" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-keyboard-tracking-view" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-notifications" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-orientation-locker" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-slider" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-splash-screen" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-video" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-webview" "${PODS_CONFIGURATION_BUILD_DIR}/rn-extensions-share" "${PODS_CONFIGURATION_BUILD_DIR}/rn-fetch-blob"
OTHER_LDFLAGS = $(inherited) -ObjC -l"BugsnagReactNative" -l"DoubleConversion" -l"FBReactNativeSpec" -l"FirebaseCore" -l"FirebaseCoreDiagnostics" -l"FirebaseInstanceID" -l"Folly" -l"GoogleDataTransport" -l"GoogleDataTransportCCTSupport" -l"GoogleUtilities" -l"KeyCommands" -l"QBImagePickerController" -l"RCTTypeSafety" -l"RNAudio" -l"RNDeviceInfo" -l"RNFastImage" -l"RNFirebase" -l"RNGestureHandler" -l"RNImageCropPicker" -l"RNLocalize" -l"RNReanimated" -l"RNScreens" -l"RNUserDefaults" -l"RNVectorIcons" -l"RSKImageCropper" -l"React-Core" -l"React-CoreModules" -l"React-RCTActionSheet" -l"React-RCTAnimation" -l"React-RCTBlob" -l"React-RCTImage" -l"React-RCTLinking" -l"React-RCTNetwork" -l"React-RCTSettings" -l"React-RCTText" -l"React-RCTVibration" -l"React-cxxreact" -l"React-jsi" -l"React-jsiexecutor" -l"React-jsinspector" -l"ReactCommon" -l"SDWebImage" -l"SDWebImageWebPCoder" -l"Yoga" -l"c++" -l"glog" -l"libwebp" -l"nanopb" -l"react-native-background-timer" -l"react-native-document-picker" -l"react-native-jitsi-meet" -l"react-native-keyboard-input" -l"react-native-keyboard-tracking-view" -l"react-native-notifications" -l"react-native-orientation-locker" -l"react-native-slider" -l"react-native-splash-screen" -l"react-native-video" -l"react-native-webview" -l"rn-extensions-share" -l"rn-fetch-blob" -l"sqlite3" -l"stdc++" -l"z" -framework "AVFoundation" -framework "Crashlytics" -framework "FIRAnalyticsConnector" -framework "Fabric" -framework "FirebaseAnalytics" -framework "Foundation" -framework "GoogleAppMeasurement" -framework "ImageIO" -framework "JavaScriptCore" -framework "JitsiMeet" -framework "MessageUI" -framework "Photos" -framework "QuartzCore" -framework "Security" -framework "StoreKit" -framework "SystemConfiguration" -framework "UIKit" -framework "WebRTC"
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.

View File

@ -1,9 +1,9 @@
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Crashlytics/iOS" "${PODS_ROOT}/Fabric/iOS" "${PODS_ROOT}/FirebaseAnalytics/Frameworks" "${PODS_ROOT}/GoogleAppMeasurement/Frameworks" "${PODS_ROOT}/JitsiMeetSDK/Frameworks"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) SD_WEBP=1 $(inherited) PB_FIELD_32BIT=1 PB_NO_PACKED_STRUCTS=1 PB_ENABLE_MALLOC=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/BugsnagReactNative" "${PODS_ROOT}/Headers/Public/DoubleConversion" "${PODS_ROOT}/Headers/Public/EXAV" "${PODS_ROOT}/Headers/Public/EXAppLoaderProvider" "${PODS_ROOT}/Headers/Public/EXConstants" "${PODS_ROOT}/Headers/Public/EXFileSystem" "${PODS_ROOT}/Headers/Public/EXHaptics" "${PODS_ROOT}/Headers/Public/EXPermissions" "${PODS_ROOT}/Headers/Public/EXWebBrowser" "${PODS_ROOT}/Headers/Public/FBLazyVector" "${PODS_ROOT}/Headers/Public/FBReactNativeSpec" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseCoreDiagnostics" "${PODS_ROOT}/Headers/Public/FirebaseCoreDiagnosticsInterop" "${PODS_ROOT}/Headers/Public/FirebaseInstanceID" "${PODS_ROOT}/Headers/Public/GoogleDataTransport" "${PODS_ROOT}/Headers/Public/GoogleDataTransportCCTSupport" "${PODS_ROOT}/Headers/Public/GoogleUtilities" "${PODS_ROOT}/Headers/Public/QBImagePickerController" "${PODS_ROOT}/Headers/Public/RCTRequired" "${PODS_ROOT}/Headers/Public/RCTTypeSafety" "${PODS_ROOT}/Headers/Public/RNAudio" "${PODS_ROOT}/Headers/Public/RNDeviceInfo" "${PODS_ROOT}/Headers/Public/RNFastImage" "${PODS_ROOT}/Headers/Public/RNFirebase" "${PODS_ROOT}/Headers/Public/RNGestureHandler" "${PODS_ROOT}/Headers/Public/RNImageCropPicker" "${PODS_ROOT}/Headers/Public/RNLocalize" "${PODS_ROOT}/Headers/Public/RNReanimated" "${PODS_ROOT}/Headers/Public/RNScreens" "${PODS_ROOT}/Headers/Public/RNUserDefaults" "${PODS_ROOT}/Headers/Public/RNVectorIcons" "${PODS_ROOT}/Headers/Public/RSKImageCropper" "${PODS_ROOT}/Headers/Public/React-Core" "${PODS_ROOT}/Headers/Public/React-RCTBlob" "${PODS_ROOT}/Headers/Public/React-RCTText" "${PODS_ROOT}/Headers/Public/React-cxxreact" "${PODS_ROOT}/Headers/Public/React-jsi" "${PODS_ROOT}/Headers/Public/React-jsiexecutor" "${PODS_ROOT}/Headers/Public/React-jsinspector" "${PODS_ROOT}/Headers/Public/ReactCommon" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SDWebImageWebPCoder" "${PODS_ROOT}/Headers/Public/UMBarCodeScannerInterface" "${PODS_ROOT}/Headers/Public/UMCameraInterface" "${PODS_ROOT}/Headers/Public/UMConstantsInterface" "${PODS_ROOT}/Headers/Public/UMCore" "${PODS_ROOT}/Headers/Public/UMFaceDetectorInterface" "${PODS_ROOT}/Headers/Public/UMFileSystemInterface" "${PODS_ROOT}/Headers/Public/UMFontInterface" "${PODS_ROOT}/Headers/Public/UMImageLoaderInterface" "${PODS_ROOT}/Headers/Public/UMPermissionsInterface" "${PODS_ROOT}/Headers/Public/UMReactNativeAdapter" "${PODS_ROOT}/Headers/Public/UMSensorsInterface" "${PODS_ROOT}/Headers/Public/UMTaskManagerInterface" "${PODS_ROOT}/Headers/Public/Yoga" "${PODS_ROOT}/Headers/Public/glog" "${PODS_ROOT}/Headers/Public/libwebp" "${PODS_ROOT}/Headers/Public/nanopb" "${PODS_ROOT}/Headers/Public/react-native-background-timer" "${PODS_ROOT}/Headers/Public/react-native-document-picker" "${PODS_ROOT}/Headers/Public/react-native-jitsi-meet" "${PODS_ROOT}/Headers/Public/react-native-keyboard-input" "${PODS_ROOT}/Headers/Public/react-native-keyboard-tracking-view" "${PODS_ROOT}/Headers/Public/react-native-notifications" "${PODS_ROOT}/Headers/Public/react-native-orientation-locker" "${PODS_ROOT}/Headers/Public/react-native-slider" "${PODS_ROOT}/Headers/Public/react-native-splash-screen" "${PODS_ROOT}/Headers/Public/react-native-video" "${PODS_ROOT}/Headers/Public/react-native-webview" "${PODS_ROOT}/Headers/Public/rn-extensions-share" "${PODS_ROOT}/Headers/Public/rn-fetch-blob" $(inherited) ${PODS_ROOT}/Firebase/CoreOnly/Sources "$(PODS_ROOT)/Headers/Private/React-Core"
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/BugsnagReactNative" "${PODS_ROOT}/Headers/Public/DoubleConversion" "${PODS_ROOT}/Headers/Public/EXAV" "${PODS_ROOT}/Headers/Public/EXAppLoaderProvider" "${PODS_ROOT}/Headers/Public/EXConstants" "${PODS_ROOT}/Headers/Public/EXFileSystem" "${PODS_ROOT}/Headers/Public/EXHaptics" "${PODS_ROOT}/Headers/Public/EXPermissions" "${PODS_ROOT}/Headers/Public/EXWebBrowser" "${PODS_ROOT}/Headers/Public/FBLazyVector" "${PODS_ROOT}/Headers/Public/FBReactNativeSpec" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseCoreDiagnostics" "${PODS_ROOT}/Headers/Public/FirebaseCoreDiagnosticsInterop" "${PODS_ROOT}/Headers/Public/FirebaseInstanceID" "${PODS_ROOT}/Headers/Public/GoogleDataTransport" "${PODS_ROOT}/Headers/Public/GoogleDataTransportCCTSupport" "${PODS_ROOT}/Headers/Public/GoogleUtilities" "${PODS_ROOT}/Headers/Public/KeyCommands" "${PODS_ROOT}/Headers/Public/QBImagePickerController" "${PODS_ROOT}/Headers/Public/RCTRequired" "${PODS_ROOT}/Headers/Public/RCTTypeSafety" "${PODS_ROOT}/Headers/Public/RNAudio" "${PODS_ROOT}/Headers/Public/RNDeviceInfo" "${PODS_ROOT}/Headers/Public/RNFastImage" "${PODS_ROOT}/Headers/Public/RNFirebase" "${PODS_ROOT}/Headers/Public/RNGestureHandler" "${PODS_ROOT}/Headers/Public/RNImageCropPicker" "${PODS_ROOT}/Headers/Public/RNLocalize" "${PODS_ROOT}/Headers/Public/RNReanimated" "${PODS_ROOT}/Headers/Public/RNScreens" "${PODS_ROOT}/Headers/Public/RNUserDefaults" "${PODS_ROOT}/Headers/Public/RNVectorIcons" "${PODS_ROOT}/Headers/Public/RSKImageCropper" "${PODS_ROOT}/Headers/Public/React-Core" "${PODS_ROOT}/Headers/Public/React-RCTBlob" "${PODS_ROOT}/Headers/Public/React-RCTText" "${PODS_ROOT}/Headers/Public/React-cxxreact" "${PODS_ROOT}/Headers/Public/React-jsi" "${PODS_ROOT}/Headers/Public/React-jsiexecutor" "${PODS_ROOT}/Headers/Public/React-jsinspector" "${PODS_ROOT}/Headers/Public/ReactCommon" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SDWebImageWebPCoder" "${PODS_ROOT}/Headers/Public/UMBarCodeScannerInterface" "${PODS_ROOT}/Headers/Public/UMCameraInterface" "${PODS_ROOT}/Headers/Public/UMConstantsInterface" "${PODS_ROOT}/Headers/Public/UMCore" "${PODS_ROOT}/Headers/Public/UMFaceDetectorInterface" "${PODS_ROOT}/Headers/Public/UMFileSystemInterface" "${PODS_ROOT}/Headers/Public/UMFontInterface" "${PODS_ROOT}/Headers/Public/UMImageLoaderInterface" "${PODS_ROOT}/Headers/Public/UMPermissionsInterface" "${PODS_ROOT}/Headers/Public/UMReactNativeAdapter" "${PODS_ROOT}/Headers/Public/UMSensorsInterface" "${PODS_ROOT}/Headers/Public/UMTaskManagerInterface" "${PODS_ROOT}/Headers/Public/Yoga" "${PODS_ROOT}/Headers/Public/glog" "${PODS_ROOT}/Headers/Public/libwebp" "${PODS_ROOT}/Headers/Public/nanopb" "${PODS_ROOT}/Headers/Public/react-native-background-timer" "${PODS_ROOT}/Headers/Public/react-native-document-picker" "${PODS_ROOT}/Headers/Public/react-native-jitsi-meet" "${PODS_ROOT}/Headers/Public/react-native-keyboard-input" "${PODS_ROOT}/Headers/Public/react-native-keyboard-tracking-view" "${PODS_ROOT}/Headers/Public/react-native-notifications" "${PODS_ROOT}/Headers/Public/react-native-orientation-locker" "${PODS_ROOT}/Headers/Public/react-native-slider" "${PODS_ROOT}/Headers/Public/react-native-splash-screen" "${PODS_ROOT}/Headers/Public/react-native-video" "${PODS_ROOT}/Headers/Public/react-native-webview" "${PODS_ROOT}/Headers/Public/rn-extensions-share" "${PODS_ROOT}/Headers/Public/rn-fetch-blob" $(inherited) ${PODS_ROOT}/Firebase/CoreOnly/Sources "$(PODS_ROOT)/Headers/Private/React-Core"
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' '@executable_path/../../Frameworks'
LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BugsnagReactNative" "${PODS_CONFIGURATION_BUILD_DIR}/DoubleConversion" "${PODS_CONFIGURATION_BUILD_DIR}/FBReactNativeSpec" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreDiagnostics" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstanceID" "${PODS_CONFIGURATION_BUILD_DIR}/Folly" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransportCCTSupport" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/QBImagePickerController" "${PODS_CONFIGURATION_BUILD_DIR}/RCTTypeSafety" "${PODS_CONFIGURATION_BUILD_DIR}/RNAudio" "${PODS_CONFIGURATION_BUILD_DIR}/RNDeviceInfo" "${PODS_CONFIGURATION_BUILD_DIR}/RNFastImage" "${PODS_CONFIGURATION_BUILD_DIR}/RNFirebase" "${PODS_CONFIGURATION_BUILD_DIR}/RNGestureHandler" "${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker" "${PODS_CONFIGURATION_BUILD_DIR}/RNLocalize" "${PODS_CONFIGURATION_BUILD_DIR}/RNReanimated" "${PODS_CONFIGURATION_BUILD_DIR}/RNScreens" "${PODS_CONFIGURATION_BUILD_DIR}/RNUserDefaults" "${PODS_CONFIGURATION_BUILD_DIR}/RNVectorIcons" "${PODS_CONFIGURATION_BUILD_DIR}/RSKImageCropper" "${PODS_CONFIGURATION_BUILD_DIR}/React-Core" "${PODS_CONFIGURATION_BUILD_DIR}/React-CoreModules" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTActionSheet" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTAnimation" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTBlob" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTImage" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTLinking" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTNetwork" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTSettings" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTText" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTVibration" "${PODS_CONFIGURATION_BUILD_DIR}/React-cxxreact" "${PODS_CONFIGURATION_BUILD_DIR}/React-jsi" "${PODS_CONFIGURATION_BUILD_DIR}/React-jsiexecutor" "${PODS_CONFIGURATION_BUILD_DIR}/React-jsinspector" "${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder" "${PODS_CONFIGURATION_BUILD_DIR}/Yoga" "${PODS_CONFIGURATION_BUILD_DIR}/glog" "${PODS_CONFIGURATION_BUILD_DIR}/libwebp" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-background-timer" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-document-picker" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-jitsi-meet" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-keyboard-input" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-keyboard-tracking-view" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-notifications" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-orientation-locker" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-slider" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-splash-screen" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-video" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-webview" "${PODS_CONFIGURATION_BUILD_DIR}/rn-extensions-share" "${PODS_CONFIGURATION_BUILD_DIR}/rn-fetch-blob"
OTHER_LDFLAGS = $(inherited) -ObjC -l"BugsnagReactNative" -l"DoubleConversion" -l"FBReactNativeSpec" -l"FirebaseCore" -l"FirebaseCoreDiagnostics" -l"FirebaseInstanceID" -l"Folly" -l"GoogleDataTransport" -l"GoogleDataTransportCCTSupport" -l"GoogleUtilities" -l"QBImagePickerController" -l"RCTTypeSafety" -l"RNAudio" -l"RNDeviceInfo" -l"RNFastImage" -l"RNFirebase" -l"RNGestureHandler" -l"RNImageCropPicker" -l"RNLocalize" -l"RNReanimated" -l"RNScreens" -l"RNUserDefaults" -l"RNVectorIcons" -l"RSKImageCropper" -l"React-Core" -l"React-CoreModules" -l"React-RCTActionSheet" -l"React-RCTAnimation" -l"React-RCTBlob" -l"React-RCTImage" -l"React-RCTLinking" -l"React-RCTNetwork" -l"React-RCTSettings" -l"React-RCTText" -l"React-RCTVibration" -l"React-cxxreact" -l"React-jsi" -l"React-jsiexecutor" -l"React-jsinspector" -l"ReactCommon" -l"SDWebImage" -l"SDWebImageWebPCoder" -l"Yoga" -l"c++" -l"glog" -l"libwebp" -l"nanopb" -l"react-native-background-timer" -l"react-native-document-picker" -l"react-native-jitsi-meet" -l"react-native-keyboard-input" -l"react-native-keyboard-tracking-view" -l"react-native-notifications" -l"react-native-orientation-locker" -l"react-native-slider" -l"react-native-splash-screen" -l"react-native-video" -l"react-native-webview" -l"rn-extensions-share" -l"rn-fetch-blob" -l"sqlite3" -l"stdc++" -l"z" -framework "AVFoundation" -framework "Crashlytics" -framework "FIRAnalyticsConnector" -framework "Fabric" -framework "FirebaseAnalytics" -framework "Foundation" -framework "GoogleAppMeasurement" -framework "ImageIO" -framework "JavaScriptCore" -framework "JitsiMeet" -framework "MessageUI" -framework "Photos" -framework "QuartzCore" -framework "Security" -framework "StoreKit" -framework "SystemConfiguration" -framework "UIKit" -framework "WebRTC"
LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BugsnagReactNative" "${PODS_CONFIGURATION_BUILD_DIR}/DoubleConversion" "${PODS_CONFIGURATION_BUILD_DIR}/FBReactNativeSpec" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreDiagnostics" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstanceID" "${PODS_CONFIGURATION_BUILD_DIR}/Folly" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransportCCTSupport" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/KeyCommands" "${PODS_CONFIGURATION_BUILD_DIR}/QBImagePickerController" "${PODS_CONFIGURATION_BUILD_DIR}/RCTTypeSafety" "${PODS_CONFIGURATION_BUILD_DIR}/RNAudio" "${PODS_CONFIGURATION_BUILD_DIR}/RNDeviceInfo" "${PODS_CONFIGURATION_BUILD_DIR}/RNFastImage" "${PODS_CONFIGURATION_BUILD_DIR}/RNFirebase" "${PODS_CONFIGURATION_BUILD_DIR}/RNGestureHandler" "${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker" "${PODS_CONFIGURATION_BUILD_DIR}/RNLocalize" "${PODS_CONFIGURATION_BUILD_DIR}/RNReanimated" "${PODS_CONFIGURATION_BUILD_DIR}/RNScreens" "${PODS_CONFIGURATION_BUILD_DIR}/RNUserDefaults" "${PODS_CONFIGURATION_BUILD_DIR}/RNVectorIcons" "${PODS_CONFIGURATION_BUILD_DIR}/RSKImageCropper" "${PODS_CONFIGURATION_BUILD_DIR}/React-Core" "${PODS_CONFIGURATION_BUILD_DIR}/React-CoreModules" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTActionSheet" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTAnimation" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTBlob" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTImage" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTLinking" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTNetwork" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTSettings" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTText" "${PODS_CONFIGURATION_BUILD_DIR}/React-RCTVibration" "${PODS_CONFIGURATION_BUILD_DIR}/React-cxxreact" "${PODS_CONFIGURATION_BUILD_DIR}/React-jsi" "${PODS_CONFIGURATION_BUILD_DIR}/React-jsiexecutor" "${PODS_CONFIGURATION_BUILD_DIR}/React-jsinspector" "${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder" "${PODS_CONFIGURATION_BUILD_DIR}/Yoga" "${PODS_CONFIGURATION_BUILD_DIR}/glog" "${PODS_CONFIGURATION_BUILD_DIR}/libwebp" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-background-timer" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-document-picker" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-jitsi-meet" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-keyboard-input" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-keyboard-tracking-view" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-notifications" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-orientation-locker" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-slider" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-splash-screen" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-video" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-webview" "${PODS_CONFIGURATION_BUILD_DIR}/rn-extensions-share" "${PODS_CONFIGURATION_BUILD_DIR}/rn-fetch-blob"
OTHER_LDFLAGS = $(inherited) -ObjC -l"BugsnagReactNative" -l"DoubleConversion" -l"FBReactNativeSpec" -l"FirebaseCore" -l"FirebaseCoreDiagnostics" -l"FirebaseInstanceID" -l"Folly" -l"GoogleDataTransport" -l"GoogleDataTransportCCTSupport" -l"GoogleUtilities" -l"KeyCommands" -l"QBImagePickerController" -l"RCTTypeSafety" -l"RNAudio" -l"RNDeviceInfo" -l"RNFastImage" -l"RNFirebase" -l"RNGestureHandler" -l"RNImageCropPicker" -l"RNLocalize" -l"RNReanimated" -l"RNScreens" -l"RNUserDefaults" -l"RNVectorIcons" -l"RSKImageCropper" -l"React-Core" -l"React-CoreModules" -l"React-RCTActionSheet" -l"React-RCTAnimation" -l"React-RCTBlob" -l"React-RCTImage" -l"React-RCTLinking" -l"React-RCTNetwork" -l"React-RCTSettings" -l"React-RCTText" -l"React-RCTVibration" -l"React-cxxreact" -l"React-jsi" -l"React-jsiexecutor" -l"React-jsinspector" -l"ReactCommon" -l"SDWebImage" -l"SDWebImageWebPCoder" -l"Yoga" -l"c++" -l"glog" -l"libwebp" -l"nanopb" -l"react-native-background-timer" -l"react-native-document-picker" -l"react-native-jitsi-meet" -l"react-native-keyboard-input" -l"react-native-keyboard-tracking-view" -l"react-native-notifications" -l"react-native-orientation-locker" -l"react-native-slider" -l"react-native-splash-screen" -l"react-native-video" -l"react-native-webview" -l"rn-extensions-share" -l"rn-fetch-blob" -l"sqlite3" -l"stdc++" -l"z" -framework "AVFoundation" -framework "Crashlytics" -framework "FIRAnalyticsConnector" -framework "Fabric" -framework "FirebaseAnalytics" -framework "Foundation" -framework "GoogleAppMeasurement" -framework "ImageIO" -framework "JavaScriptCore" -framework "JitsiMeet" -framework "MessageUI" -framework "Photos" -framework "QuartzCore" -framework "Security" -framework "StoreKit" -framework "SystemConfiguration" -framework "UIKit" -framework "WebRTC"
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.

View File

@ -23,6 +23,7 @@
1E1EA81A2326CD5100E22452 /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E1EA8192326CD5100E22452 /* libsqlite3.tbd */; };
1E25743422CBA2CF005A877F /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7ACD4853222860DE00442C55 /* JavaScriptCore.framework */; };
1E55FDB32320675C0048D2F9 /* libWatermelonDB.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7AAA749B23043AD300F1ADE9 /* libWatermelonDB.a */; };
1E7B75582350CF480050D8CB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1E7B75562350CF480050D8CB /* LaunchScreen.storyboard */; };
1EC6ACB722CB9FC300A41C61 /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1EC6ACB522CB9FC300A41C61 /* MainInterface.storyboard */; };
1EC6ACBB22CB9FC300A41C61 /* ShareRocketChatRN.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 1EC6ACB022CB9FC300A41C61 /* ShareRocketChatRN.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
1EC6ACF622CBA01500A41C61 /* ShareRocketChatRN.m in Sources */ = {isa = PBXBuildFile; fileRef = 1EC6ACF522CBA01500A41C61 /* ShareRocketChatRN.m */; };
@ -90,6 +91,7 @@
1E1EA8152326CD4500E22452 /* VideoToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = VideoToolbox.framework; path = System/Library/Frameworks/VideoToolbox.framework; sourceTree = SDKROOT; };
1E1EA8172326CD4B00E22452 /* libc.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libc.tbd; path = usr/lib/libc.tbd; sourceTree = SDKROOT; };
1E1EA8192326CD5100E22452 /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = usr/lib/libsqlite3.tbd; sourceTree = SDKROOT; };
1E7B75562350CF480050D8CB /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = "<group>"; };
1EC6ACB022CB9FC300A41C61 /* ShareRocketChatRN.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = ShareRocketChatRN.appex; sourceTree = BUILT_PRODUCTS_DIR; };
1EC6ACB622CB9FC300A41C61 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = "<group>"; };
1EC6ACB822CB9FC300A41C61 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@ -153,6 +155,7 @@
children = (
7A006F13229C83B600803143 /* GoogleService-Info.plist */,
60B2A6A31FC4588700BD58E5 /* RocketChatRN.entitlements */,
1E7B75562350CF480050D8CB /* LaunchScreen.storyboard */,
008F07F21AC5B25A0029DE68 /* main.jsbundle */,
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
13B07FB01A68108700A75B9A /* AppDelegate.m */,
@ -398,6 +401,7 @@
files = (
7A55F1C52236D541005109A0 /* custom.ttf in Resources */,
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
1E7B75582350CF480050D8CB /* LaunchScreen.storyboard in Resources */,
7A006F14229C83B600803143 /* GoogleService-Info.plist in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -679,7 +683,7 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
APPLICATION_EXTENSION_API_ONLY = NO;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = "";
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = RocketChatRN/RocketChatRN.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer";
@ -699,6 +703,7 @@
"$(SRCROOT)/../node_modules/@nozbe/watermelondb/native/ios/WatermelonDB/SupportingFiles/**",
);
INFOPLIST_FILE = RocketChatRN/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
@ -716,6 +721,7 @@
SWIFT_OBJC_BRIDGING_HEADER = "RocketChatRN-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
@ -727,7 +733,7 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
APPLICATION_EXTENSION_API_ONLY = NO;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = "";
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = RocketChatRN/RocketChatRN.entitlements;
CODE_SIGN_IDENTITY = "iPhone Distribution";
@ -747,6 +753,7 @@
"$(SRCROOT)/../node_modules/@nozbe/watermelondb/native/ios/WatermelonDB/SupportingFiles/**",
);
INFOPLIST_FILE = RocketChatRN/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
@ -763,6 +770,7 @@
PROVISIONING_PROFILE_SPECIFIER = "match AppStore chat.rocket.reactnative";
SWIFT_OBJC_BRIDGING_HEADER = "RocketChatRN-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
@ -809,7 +817,7 @@
"$(inherited)",
"$(SRCROOT)/../node_modules/rn-extensions-share/ios/**",
"$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**",
"$PODS_CONFIGURATION_BUILD_DIR/Firebase",
$PODS_CONFIGURATION_BUILD_DIR/Firebase,
);
INFOPLIST_FILE = ShareRocketChatRN/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
@ -876,7 +884,7 @@
PROVISIONING_PROFILE_SPECIFIER = "Development chat.rocket.reactnative.ShareExtension";
SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
@ -922,7 +930,7 @@
"$(inherited)",
"$(SRCROOT)/../node_modules/rn-extensions-share/ios/**",
"$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**",
"$PODS_CONFIGURATION_BUILD_DIR/Firebase",
$PODS_CONFIGURATION_BUILD_DIR/Firebase,
);
INFOPLIST_FILE = ShareRocketChatRN/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
@ -988,7 +996,7 @@
PROVISIONING_PROFILE_SPECIFIER = "chat.rocket.reactnative.ShareExtension AppStore";
SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};

View File

@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "icon.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "icon@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "icon@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -1,135 +0,0 @@
{
"images" : [
{
"orientation": "portrait",
"idiom": "iphone",
"extent": "full-screen",
"minimum-system-version": "11.0",
"filename": "Default-Portrait-812h@3x.png",
"subtype": "2436h",
"scale": "3x"
},
{
"orientation": "landscape",
"idiom": "iphone",
"extent": "full-screen",
"filename": "Default-Landscape-812h@3x.png",
"minimum-system-version": "11.0",
"subtype": "2436h",
"scale": "3x"
},
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "736h",
"filename" : "Default-Portrait-736h@3x.png",
"minimum-system-version" : "8.0",
"orientation" : "portrait",
"scale" : "3x"
},
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "736h",
"filename" : "Default-Landscape-736h@3x.png",
"minimum-system-version" : "8.0",
"orientation" : "landscape",
"scale" : "3x"
},
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "667h",
"filename" : "Default-667h@2x.png",
"minimum-system-version" : "8.0",
"orientation" : "portrait",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "iphone",
"filename" : "Default@2x.png",
"extent" : "full-screen",
"minimum-system-version" : "7.0",
"scale" : "2x"
},
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "retina4",
"filename" : "Default-568h@2x.png",
"minimum-system-version" : "7.0",
"orientation" : "portrait",
"scale" : "2x"
},
{
"orientation" : "landscape",
"idiom" : "ipad",
"filename" : "Default-Landscape.png",
"extent" : "full-screen",
"minimum-system-version" : "7.0",
"scale" : "1x"
},
{
"orientation" : "landscape",
"idiom" : "ipad",
"filename" : "Default-Landscape@2x.png",
"extent" : "full-screen",
"minimum-system-version" : "7.0",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "iphone",
"extent" : "full-screen",
"scale" : "1x"
},
{
"orientation" : "portrait",
"idiom" : "iphone",
"extent" : "full-screen",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "iphone",
"extent" : "full-screen",
"subtype" : "retina4",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "ipad",
"filename" : "Default-Portrait.png",
"extent" : "full-screen",
"scale" : "1x"
},
{
"orientation" : "portrait",
"idiom" : "ipad",
"filename" : "Default-Portrait@2x.png",
"extent" : "full-screen",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "ipad",
"filename" : "Default-Portrait.png",
"extent" : "full-screen",
"minimum-system-version" : "7.0",
"scale" : "1x"
},
{
"orientation" : "portrait",
"idiom" : "ipad",
"filename" : "Default-Portrait@2x.png",
"extent" : "full-screen",
"minimum-system-version" : "7.0",
"scale" : "2x"
},
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View File

@ -78,10 +78,17 @@
<array>
<string>custom.ttf</string>
</array>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
</dict>
<key>UIBackgroundModes</key>
<array>
<string>voip</string>
</array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
@ -91,6 +98,7 @@
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>

View File

@ -36,6 +36,7 @@
"expo-file-system": "^6.0.2",
"expo-haptics": "6.0.0",
"expo-web-browser": "^6.0.0",
"hoist-non-react-statics": "^3.3.0",
"i18n-js": "3.5.0",
"js-base64": "^2.5.1",
"js-sha256": "^0.9.0",
@ -61,11 +62,11 @@
"react-native-keyboard-aware-scroll-view": "0.9.1",
"react-native-keyboard-input": "^5.3.1",
"react-native-keyboard-tracking-view": "^5.5.0",
"react-native-keycommands": "2.0.3",
"react-native-localize": "1.3.1",
"react-native-mime-types": "^2.2.1",
"react-native-modal": "11.5.3",
"react-native-notifications": "^2.0.6",
"react-native-optimized-flatlist": "^1.0.4",
"react-native-orientation-locker": "1.1.6",
"react-native-picker-select": "6.3.3",
"react-native-platform-touchable": "^1.1.1",

View File

@ -141,6 +141,153 @@ index a134d2e..a88c099 100644
[self _sendFrameWithOpcode:RCTSROpCodeConnectionClose data:payload];
});
}
diff --git a/node_modules/react-native/React/Base/RCTKeyCommands.h b/node_modules/react-native/React/Base/RCTKeyCommands.h
index 4c9c1fe..8c0ebc3 100644
--- a/node_modules/react-native/React/Base/RCTKeyCommands.h
+++ b/node_modules/react-native/React/Base/RCTKeyCommands.h
@@ -14,10 +14,15 @@
/**
* Register a single-press keyboard command.
*/
-- (void)registerKeyCommandWithInput:(NSString *)input
+ - (void)registerKeyCommandWithInput:(NSString *)input
modifierFlags:(UIKeyModifierFlags)flags
action:(void (^)(UIKeyCommand *command))block;
+- (void)registerKeyCommand:(NSString *)input
+ modifierFlags:(UIKeyModifierFlags)flags
+ discoverabilityTitle:(NSString *)discoverabilityTitle
+ action:(void (^)(UIKeyCommand *))block;
+
/**
* Unregister a single-press keyboard command.
*/
diff --git a/node_modules/react-native/React/Base/RCTKeyCommands.m b/node_modules/react-native/React/Base/RCTKeyCommands.m
index 8f8f19b..150bcfe 100644
--- a/node_modules/react-native/React/Base/RCTKeyCommands.m
+++ b/node_modules/react-native/React/Base/RCTKeyCommands.m
@@ -12,8 +12,6 @@
#import "RCTDefines.h"
#import "RCTUtils.h"
-#if RCT_DEV
-
@interface RCTKeyCommand : NSObject <NSCopying>
@property (nonatomic, strong) UIKeyCommand *keyCommand;
@@ -114,7 +112,9 @@ - (void)RCT_handleKeyCommand:(UIKeyCommand *)key
// NOTE: throttle the key handler because on iOS 9 the handleKeyCommand:
// method gets called repeatedly if the command key is held down.
static NSTimeInterval lastCommand = 0;
- if (CACurrentMediaTime() - lastCommand > 0.5) {
+ if (CACurrentMediaTime() - lastCommand > 0.5 ||
+ [key.input isEqualToString:@"UIKeyInputUpArrow"] || // repeat command if is scroll
+ [key.input isEqualToString:@"UIKeyInputDownArrow"]) {
for (RCTKeyCommand *command in [RCTKeyCommands sharedInstance].commands) {
if ([command.keyCommand.input isEqualToString:key.input] &&
command.keyCommand.modifierFlags == key.modifierFlags) {
@@ -184,6 +184,8 @@ - (void)RCT_handleDoublePressKeyCommand:(UIKeyCommand *)key
@end
+#if RCT_DEV
+
@implementation RCTKeyCommands
+ (void)initialize
@@ -228,6 +230,23 @@ - (void)registerKeyCommandWithInput:(NSString *)input
[_commands addObject:keyCommand];
}
+- (void)registerKeyCommand:(NSString *)input
+ modifierFlags:(UIKeyModifierFlags)flags
+ discoverabilityTitle:(NSString *)discoverabilityTitle
+ action:(void (^)(UIKeyCommand *))block
+{
+ RCTAssertMainQueue();
+
+ UIKeyCommand *command = [UIKeyCommand keyCommandWithInput:input
+ modifierFlags:flags
+ action:@selector(RCT_handleKeyCommand:)
+ discoverabilityTitle:discoverabilityTitle];
+
+ RCTKeyCommand *keyCommand = [[RCTKeyCommand alloc] initWithKeyCommand:command block:block];
+ [_commands removeObject:keyCommand];
+ [_commands addObject:keyCommand];
+}
+
- (void)unregisterKeyCommandWithInput:(NSString *)input
modifierFlags:(UIKeyModifierFlags)flags
{
@@ -301,9 +320,48 @@ - (BOOL)isDoublePressKeyCommandRegisteredForInput:(NSString *)input
@implementation RCTKeyCommands
++ (void)initialize
+{
+ // swizzle UIResponder
+ RCTSwapInstanceMethods([UIResponder class],
+ @selector(keyCommands),
+ @selector(RCT_keyCommands));
+}
+
+ (instancetype)sharedInstance
{
- return nil;
+ static RCTKeyCommands *sharedInstance;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ sharedInstance = [self new];
+ });
+
+ return sharedInstance;
+}
+
+- (instancetype)init
+{
+ if ((self = [super init])) {
+ _commands = [NSMutableSet new];
+ }
+ return self;
+}
+
+- (void)registerKeyCommand:(NSString *)input
+ modifierFlags:(UIKeyModifierFlags)flags
+ discoverabilityTitle:(NSString *)discoverabilityTitle
+ action:(void (^)(UIKeyCommand *))block
+{
+ RCTAssertMainQueue();
+
+ UIKeyCommand *command = [UIKeyCommand keyCommandWithInput:input
+ modifierFlags:flags
+ action:@selector(RCT_handleKeyCommand:)
+ discoverabilityTitle:discoverabilityTitle];
+
+ RCTKeyCommand *keyCommand = [[RCTKeyCommand alloc] initWithKeyCommand:command block:block];
+ [_commands removeObject:keyCommand];
+ [_commands addObject:keyCommand];
}
- (void)registerKeyCommandWithInput:(NSString *)input
@@ -311,7 +369,17 @@ - (void)registerKeyCommandWithInput:(NSString *)input
action:(void (^)(UIKeyCommand *))block {}
- (void)unregisterKeyCommandWithInput:(NSString *)input
- modifierFlags:(UIKeyModifierFlags)flags {}
+ modifierFlags:(UIKeyModifierFlags)flags
+{
+ RCTAssertMainQueue();
+
+ for (RCTKeyCommand *command in _commands.allObjects) {
+ if ([command matchesInput:input flags:flags]) {
+ [_commands removeObject:command];
+ break;
+ }
+ }
+}
- (BOOL)isKeyCommandRegisteredForInput:(NSString *)input
modifierFlags:(UIKeyModifierFlags)flags
diff --git a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoModule.java b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoModule.java
index ef2ae93..2795802 100644
--- a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoModule.java

Some files were not shown because too many files have changed in this diff Show More