[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 { export default {
getModel: () => '', getModel: () => '',
getReadableVersion: () => '', getReadableVersion: () => '',
getBundleId: () => '' getBundleId: () => '',
isTablet: () => false
}; };

View File

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

View File

@ -1,6 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <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"> 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> </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 PropTypes from 'prop-types';
import { View } from 'react-native'; import { View } from 'react-native';
import FastImage from 'react-native-fast-image'; import FastImage from 'react-native-fast-image';
import Touch from '../utils/touch';
const formatUrl = (url, baseUrl, uriSize, avatarAuthURLFragment) => ( const formatUrl = (url, baseUrl, uriSize, avatarAuthURLFragment) => (
`${ baseUrl }${ url }?format=png&width=${ uriSize }&height=${ uriSize }${ avatarAuthURLFragment }` `${ baseUrl }${ url }?format=png&width=${ uriSize }&height=${ uriSize }${ avatarAuthURLFragment }`
); );
const Avatar = React.memo(({ 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 = { const avatarStyle = {
width: size, width: size,
@ -39,7 +40,7 @@ const Avatar = React.memo(({
} }
const image = ( let image = (
<FastImage <FastImage
style={avatarStyle} style={avatarStyle}
source={{ source={{
@ -49,6 +50,14 @@ const Avatar = React.memo(({
/> />
); );
if (onPress) {
image = (
<Touch onPress={onPress}>
{image}
</Touch>
);
}
return ( return (
<View style={[avatarStyle, style]}> <View style={[avatarStyle, style]}>
{image} {image}
@ -67,7 +76,8 @@ Avatar.propTypes = {
type: PropTypes.string, type: PropTypes.string,
children: PropTypes.object, children: PropTypes.object,
userId: PropTypes.string, userId: PropTypes.string,
token: PropTypes.string token: PropTypes.string,
onPress: PropTypes.func
}; };
Avatar.defaultProps = { Avatar.defaultProps = {

View File

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

View File

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

View File

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

View File

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

View File

@ -20,7 +20,7 @@ export default class EmojiKeyboard extends React.PureComponent {
render() { render() {
return ( return (
<View style={styles.emojiKeyboardContainer} testID='messagebox-keyboard-emoji'> <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>
); );
} }

View File

@ -11,17 +11,20 @@ import TextInput from '../TextInput';
import Button from '../Button'; import Button from '../Button';
import I18n from '../../i18n'; import I18n from '../../i18n';
import sharedStyles from '../../views/Styles'; import sharedStyles from '../../views/Styles';
import { isIOS } from '../../utils/deviceInfo'; import { isIOS, isTablet } from '../../utils/deviceInfo';
import { import {
COLOR_PRIMARY, COLOR_BACKGROUND_CONTAINER, COLOR_WHITE COLOR_PRIMARY, COLOR_BACKGROUND_CONTAINER, COLOR_WHITE
} from '../../constants/colors'; } from '../../constants/colors';
import { CustomIcon } from '../../lib/Icons'; import { CustomIcon } from '../../lib/Icons';
import { withSplit } from '../../split';
const cancelButtonColor = COLOR_BACKGROUND_CONTAINER; const cancelButtonColor = COLOR_BACKGROUND_CONTAINER;
const styles = StyleSheet.create({ const styles = StyleSheet.create({
modal: { modal: {
alignItems: 'center' width: '100%',
alignItems: 'center',
margin: 0
}, },
titleContainer: { titleContainer: {
flexDirection: 'row', flexDirection: 'row',
@ -48,6 +51,9 @@ const styles = StyleSheet.create({
marginBottom: 16, marginBottom: 16,
resizeMode: 'contain' resizeMode: 'contain'
}, },
bigPreview: {
height: 250
},
buttonContainer: { buttonContainer: {
flexDirection: 'row', flexDirection: 'row',
justifyContent: 'space-between', justifyContent: 'space-between',
@ -91,7 +97,8 @@ class UploadModal extends Component {
file: PropTypes.object, file: PropTypes.object,
close: PropTypes.func, close: PropTypes.func,
submit: PropTypes.func, submit: PropTypes.func,
window: PropTypes.object window: PropTypes.object,
split: PropTypes.bool
} }
state = { state = {
@ -113,11 +120,14 @@ class UploadModal extends Component {
shouldComponentUpdate(nextProps, nextState) { shouldComponentUpdate(nextProps, nextState) {
const { name, description, file } = this.state; const { name, description, file } = this.state;
const { window, isVisible } = this.props; const { window, isVisible, split } = this.props;
if (nextState.name !== name) { if (nextState.name !== name) {
return true; return true;
} }
if (nextProps.split !== split) {
return true;
}
if (nextState.description !== description) { if (nextState.description !== description) {
return true; return true;
} }
@ -184,9 +194,9 @@ class UploadModal extends Component {
} }
renderPreview() { renderPreview() {
const { file } = this.props; const { file, split } = this.props;
if (file.mime && file.mime.match(/image/)) { 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/)) { if (file.mime && file.mime.match(/video/)) {
return ( return (
@ -200,7 +210,7 @@ class UploadModal extends Component {
render() { render() {
const { const {
window: { width }, isVisible, close window: { width }, isVisible, close, split
} = this.props; } = this.props;
const { name, description } = this.state; const { name, description } = this.state;
return ( return (
@ -215,7 +225,7 @@ class UploadModal extends Component {
hideModalContentWhileAnimating hideModalContentWhileAnimating
avoidKeyboard avoidKeyboard
> >
<View style={[styles.container, { width: width - 32 }]}> <View style={[styles.container, { width: (isTablet ? '80%' : width - 32) }, split && sharedStyles.modal]}>
<View style={styles.titleContainer}> <View style={styles.titleContainer}>
<Text style={styles.title}>{I18n.t('Upload_file_question_mark')}</Text> <Text style={styles.title}>{I18n.t('Upload_file_question_mark')}</Text>
</View> </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 React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { import {
View, TextInput, Alert View, TextInput, Alert, Keyboard
} from 'react-native'; } from 'react-native';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { KeyboardAccessoryView } from 'react-native-keyboard-input'; import { KeyboardAccessoryView } from 'react-native-keyboard-input';
@ -25,8 +25,15 @@ import debounce from '../../utils/debounce';
import { COLOR_TEXT_DESCRIPTION } from '../../constants/colors'; import { COLOR_TEXT_DESCRIPTION } from '../../constants/colors';
import LeftButtons from './LeftButtons'; import LeftButtons from './LeftButtons';
import RightButtons from './RightButtons'; import RightButtons from './RightButtons';
import { isAndroid } from '../../utils/deviceInfo'; import { isAndroid, isTablet } from '../../utils/deviceInfo';
import { canUploadFile } from '../../utils/media'; import { canUploadFile } from '../../utils/media';
import EventEmiter from '../../utils/events';
import {
KEY_COMMAND,
handleCommandTyping,
handleCommandSubmit,
handleCommandShowUpload
} from '../../commands';
import Mentions from './Mentions'; import Mentions from './Mentions';
import MessageboxContext from './Context'; import MessageboxContext from './Context';
import { import {
@ -98,8 +105,8 @@ class MessageBox extends Component {
commandPreview: [], commandPreview: [],
showCommandPreview: false showCommandPreview: false
}; };
this.onEmojiSelected = this.onEmojiSelected.bind(this);
this.text = ''; this.text = '';
this.focused = false;
this.fileOptions = [ this.fileOptions = [
I18n.t('Cancel'), I18n.t('Cancel'),
I18n.t('Take_a_photo'), I18n.t('Take_a_photo'),
@ -162,6 +169,10 @@ class MessageBox extends Component {
if (isAndroid) { if (isAndroid) {
require('./EmojiKeyboard'); require('./EmojiKeyboard');
} }
if (isTablet) {
EventEmiter.addEventListener(KEY_COMMAND, this.handleCommands);
}
} }
componentWillReceiveProps(nextProps) { componentWillReceiveProps(nextProps) {
@ -239,12 +250,16 @@ class MessageBox extends Component {
if (this.getSlashCommands && this.getSlashCommands.stop) { if (this.getSlashCommands && this.getSlashCommands.stop) {
this.getSlashCommands.stop(); this.getSlashCommands.stop();
} }
if (isTablet) {
EventEmiter.removeListener(KEY_COMMAND, this.handleCommands);
}
} }
onChangeText = (text) => { onChangeText = (text) => {
const isTextEmpty = text.length === 0; const isTextEmpty = text.length === 0;
this.setShowSend(!isTextEmpty); this.setShowSend(!isTextEmpty);
this.debouncedOnChangeText(text); this.debouncedOnChangeText(text);
this.setInput(text);
} }
// eslint-disable-next-line react/sort-comp // eslint-disable-next-line react/sort-comp
@ -253,7 +268,6 @@ class MessageBox extends Component {
const isTextEmpty = text.length === 0; const isTextEmpty = text.length === 0;
// this.setShowSend(!isTextEmpty); // this.setShowSend(!isTextEmpty);
this.handleTyping(!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" // 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); const slashCommand = text.match(/^\/([a-z0-9._-]+) (.+)/im);
if (slashCommand) { if (slashCommand) {
@ -453,7 +467,10 @@ class MessageBox extends Component {
} }
setShowSend = (showSend) => { setShowSend = (showSend) => {
this.setState({ showSend }); const { showSend: prevShowSend } = this.state;
if (prevShowSend !== showSend) {
this.setState({ showSend });
}
} }
clearInput = () => { clearInput = () => {
@ -624,6 +641,7 @@ class MessageBox extends Component {
const message = this.text; const message = this.text;
this.clearInput(); this.clearInput();
this.debouncedOnChangeText.stop();
this.closeEmoji(); this.closeEmoji();
this.stopTrackingMention(); this.stopTrackingMention();
this.handleTyping(false); 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 = () => { renderContent = () => {
const { const {
recording, showEmojiKeyboard, showSend, mentions, trackingType, commandPreview, showCommandPreview recording, showEmojiKeyboard, showSend, mentions, trackingType, commandPreview, showCommandPreview
@ -733,6 +766,12 @@ class MessageBox extends Component {
editing, message, replying, replyCancel, user, getCustomEmoji editing, message, replying, replyCancel, user, getCustomEmoji
} = this.props; } = this.props;
const isAndroidTablet = isTablet && isAndroid ? {
multiline: false,
onSubmitEditing: this.submit,
returnKeyType: 'send'
} : {};
if (recording) { if (recording) {
return <Recording onFinish={this.finishAudioMessage} />; return <Recording onFinish={this.finishAudioMessage} />;
} }
@ -773,6 +812,7 @@ class MessageBox extends Component {
multiline multiline
placeholderTextColor={COLOR_TEXT_DESCRIPTION} placeholderTextColor={COLOR_TEXT_DESCRIPTION}
testID='messagebox-input' testID='messagebox-input'
{...isAndroidTablet}
/> />
<RightButtons <RightButtons
showSend={showSend} showSend={showSend}

View File

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

View File

@ -14,6 +14,7 @@ import { CustomIcon } from '../../lib/Icons';
import sharedStyles from '../../views/Styles'; import sharedStyles from '../../views/Styles';
import { COLOR_BACKGROUND_CONTAINER, COLOR_BORDER, COLOR_PRIMARY } from '../../constants/colors'; import { COLOR_BACKGROUND_CONTAINER, COLOR_BORDER, COLOR_PRIMARY } from '../../constants/colors';
import { isAndroid, isIOS } from '../../utils/deviceInfo'; import { isAndroid, isIOS } from '../../utils/deviceInfo';
import { withSplit } from '../../split';
const styles = StyleSheet.create({ const styles = StyleSheet.create({
audioContainer: { audioContainer: {
@ -73,12 +74,13 @@ Button.propTypes = {
}; };
Button.displayName = 'MessageAudioButton'; Button.displayName = 'MessageAudioButton';
export default class Audio extends React.Component { class Audio extends React.Component {
static propTypes = { static propTypes = {
file: PropTypes.object.isRequired, file: PropTypes.object.isRequired,
baseUrl: PropTypes.string.isRequired, baseUrl: PropTypes.string.isRequired,
user: PropTypes.object.isRequired, user: PropTypes.object.isRequired,
useMarkdown: PropTypes.bool, useMarkdown: PropTypes.bool,
split: PropTypes.bool,
getCustomEmoji: PropTypes.func getCustomEmoji: PropTypes.func
} }
@ -97,7 +99,7 @@ export default class Audio extends React.Component {
const { const {
currentTime, duration, paused, uri currentTime, duration, paused, uri
} = this.state; } = this.state;
const { file } = this.props; const { file, split } = this.props;
if (nextState.currentTime !== currentTime) { if (nextState.currentTime !== currentTime) {
return true; return true;
} }
@ -113,6 +115,9 @@ export default class Audio extends React.Component {
if (!equal(nextProps.file, file)) { if (!equal(nextProps.file, file)) {
return true; return true;
} }
if (nextProps.split !== split) {
return true;
}
return false; return false;
} }
@ -153,7 +158,7 @@ export default class Audio extends React.Component {
uri, paused, currentTime, duration uri, paused, currentTime, duration
} = this.state; } = this.state;
const { const {
user, baseUrl, file, getCustomEmoji, useMarkdown user, baseUrl, file, getCustomEmoji, useMarkdown, split
} = this.props; } = this.props;
const { description } = file; const { description } = file;
@ -163,7 +168,7 @@ export default class Audio extends React.Component {
return ( return (
<> <>
<View style={styles.audioContainer}> <View style={[styles.audioContainer, split && sharedStyles.tabletContent]}>
<Video <Video
ref={this.setRef} ref={this.setRef}
source={{ uri }} 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 Markdown from '../markdown';
import styles from './styles'; import styles from './styles';
import { formatAttachmentUrl } from '../../lib/utils'; 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 <Touchable
onPress={onPress} onPress={onPress}
style={styles.imageContainer} style={[styles.imageContainer, split && sharedStyles.tabletContent]}
background={Touchable.Ripple('#fff')} background={Touchable.Ripple('#fff')}
> >
{children} {children}
@ -28,7 +30,7 @@ const Image = React.memo(({ img }) => (
)); ));
const ImageContainer = React.memo(({ 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); const img = formatAttachmentUrl(file.image_url, user.id, user.token, baseUrl);
if (!img) { if (!img) {
@ -39,7 +41,7 @@ const ImageContainer = React.memo(({
if (file.description) { if (file.description) {
return ( return (
<Button onPress={onPress}> <Button split={split} onPress={onPress}>
<View> <View>
<Image img={img} /> <Image img={img} />
<Markdown msg={file.description} baseUrl={baseUrl} username={user.username} getCustomEmoji={getCustomEmoji} useMarkdown={useMarkdown} /> <Markdown msg={file.description} baseUrl={baseUrl} username={user.username} getCustomEmoji={getCustomEmoji} useMarkdown={useMarkdown} />
@ -49,11 +51,11 @@ const ImageContainer = React.memo(({
} }
return ( return (
<Button onPress={onPress}> <Button split={split} onPress={onPress}>
<Image img={img} /> <Image img={img} />
</Button> </Button>
); );
}, (prevProps, nextProps) => equal(prevProps.file, nextProps.file)); }, (prevProps, nextProps) => equal(prevProps.file, nextProps.file) && prevProps.split === nextProps.split);
ImageContainer.propTypes = { ImageContainer.propTypes = {
file: PropTypes.object, file: PropTypes.object,
@ -61,7 +63,8 @@ ImageContainer.propTypes = {
user: PropTypes.object, user: PropTypes.object,
useMarkdown: PropTypes.bool, useMarkdown: PropTypes.bool,
onOpenFileModal: PropTypes.func, onOpenFileModal: PropTypes.func,
getCustomEmoji: PropTypes.func getCustomEmoji: PropTypes.func,
split: PropTypes.bool
}; };
ImageContainer.displayName = 'MessageImageContainer'; ImageContainer.displayName = 'MessageImageContainer';
@ -72,8 +75,9 @@ ImageContainer.displayName = 'MessageImage';
Button.propTypes = { Button.propTypes = {
children: PropTypes.node, children: PropTypes.node,
onPress: PropTypes.func onPress: PropTypes.func,
split: PropTypes.bool
}; };
ImageContainer.displayName = 'MessageButton'; 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 openLink from '../../utils/openLink';
import sharedStyles from '../../views/Styles'; import sharedStyles from '../../views/Styles';
import { COLOR_BACKGROUND_CONTAINER, COLOR_BORDER } from '../../constants/colors'; import { COLOR_BACKGROUND_CONTAINER, COLOR_BORDER } from '../../constants/colors';
import { withSplit } from '../../split';
const styles = StyleSheet.create({ const styles = StyleSheet.create({
button: { button: {
@ -16,7 +17,7 @@ const styles = StyleSheet.create({
flexDirection: 'row', flexDirection: 'row',
alignItems: 'center', alignItems: 'center',
marginTop: 6, marginTop: 6,
alignSelf: 'flex-end', alignSelf: 'flex-start',
backgroundColor: COLOR_BACKGROUND_CONTAINER, backgroundColor: COLOR_BACKGROUND_CONTAINER,
borderColor: COLOR_BORDER, borderColor: COLOR_BORDER,
borderWidth: 1, borderWidth: 1,
@ -126,7 +127,7 @@ const Fields = React.memo(({ attachment }) => {
}, (prevProps, nextProps) => isEqual(prevProps.attachment.fields, nextProps.attachment.fields)); }, (prevProps, nextProps) => isEqual(prevProps.attachment.fields, nextProps.attachment.fields));
const Reply = React.memo(({ const Reply = React.memo(({
attachment, timeFormat, baseUrl, user, index, getCustomEmoji, useMarkdown attachment, timeFormat, baseUrl, user, index, getCustomEmoji, useMarkdown, split
}) => { }) => {
if (!attachment) { if (!attachment) {
return null; return null;
@ -146,7 +147,7 @@ const Reply = React.memo(({
return ( return (
<Touchable <Touchable
onPress={onPress} onPress={onPress}
style={[styles.button, index > 0 && styles.marginTop]} style={[styles.button, index > 0 && styles.marginTop, split && sharedStyles.tabletContent]}
background={Touchable.Ripple('#fff')} background={Touchable.Ripple('#fff')}
> >
<View style={styles.attachmentContainer}> <View style={styles.attachmentContainer}>
@ -163,7 +164,7 @@ const Reply = React.memo(({
</View> </View>
</Touchable> </Touchable>
); );
}, (prevProps, nextProps) => isEqual(prevProps.attachment, nextProps.attachment)); }, (prevProps, nextProps) => isEqual(prevProps.attachment, nextProps.attachment) && prevProps.split === nextProps.split);
Reply.propTypes = { Reply.propTypes = {
attachment: PropTypes.object, attachment: PropTypes.object,
@ -172,7 +173,8 @@ Reply.propTypes = {
user: PropTypes.object, user: PropTypes.object,
index: PropTypes.number, index: PropTypes.number,
useMarkdown: PropTypes.bool, useMarkdown: PropTypes.bool,
getCustomEmoji: PropTypes.func getCustomEmoji: PropTypes.func,
split: PropTypes.bool
}; };
Reply.displayName = 'MessageReply'; Reply.displayName = 'MessageReply';
@ -196,4 +198,4 @@ Fields.propTypes = {
}; };
Fields.displayName = 'MessageReplyFields'; Fields.displayName = 'MessageReplyFields';
export default Reply; export default withSplit(Reply);

View File

@ -10,6 +10,7 @@ import sharedStyles from '../../views/Styles';
import { import {
COLOR_BACKGROUND_CONTAINER, COLOR_BORDER, COLOR_PRIMARY COLOR_BACKGROUND_CONTAINER, COLOR_BORDER, COLOR_PRIMARY
} from '../../constants/colors'; } from '../../constants/colors';
import { withSplit } from '../../split';
const styles = StyleSheet.create({ const styles = StyleSheet.create({
button: { button: {
@ -75,7 +76,7 @@ const UrlContent = React.memo(({ title, description }) => (
}); });
const Url = React.memo(({ const Url = React.memo(({
url, index, user, baseUrl url, index, user, baseUrl, split
}) => { }) => {
if (!url) { if (!url) {
return null; return null;
@ -86,7 +87,7 @@ const Url = React.memo(({
return ( return (
<Touchable <Touchable
onPress={onPress} 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')} background={Touchable.Ripple('#fff')}
> >
<> <>
@ -95,17 +96,19 @@ const Url = React.memo(({
</> </>
</Touchable> </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) { if (!urls || urls.length === 0) {
return null; return null;
} }
return urls.map((url, index) => ( 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 = { UrlImage.propTypes = {
image: PropTypes.string, image: PropTypes.string,
@ -124,15 +127,17 @@ Url.propTypes = {
url: PropTypes.object.isRequired, url: PropTypes.object.isRequired,
index: PropTypes.number, index: PropTypes.number,
user: PropTypes.object, user: PropTypes.object,
baseUrl: PropTypes.string baseUrl: PropTypes.string,
split: PropTypes.bool
}; };
Url.displayName = 'MessageUrl'; Url.displayName = 'MessageUrl';
Urls.propTypes = { Urls.propTypes = {
urls: PropTypes.array, urls: PropTypes.array,
user: PropTypes.object, user: PropTypes.object,
baseUrl: PropTypes.string baseUrl: PropTypes.string,
split: PropTypes.bool
}; };
Urls.displayName = 'MessageUrls'; 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 Markdown from '../markdown';
import openLink from '../../utils/openLink'; import openLink from '../../utils/openLink';
import { isIOS } from '../../utils/deviceInfo'; import { isIOS, isTablet } from '../../utils/deviceInfo';
import { CustomIcon } from '../../lib/Icons'; import { CustomIcon } from '../../lib/Icons';
import { formatAttachmentUrl } from '../../lib/utils'; import { formatAttachmentUrl } from '../../lib/utils';
import sharedStyles from '../../views/Styles';
const SUPPORTED_TYPES = ['video/quicktime', 'video/mp4', ...(isIOS ? [] : ['video/3gp', 'video/mkv'])]; const SUPPORTED_TYPES = ['video/quicktime', 'video/mp4', ...(isIOS ? [] : ['video/3gp', 'video/mkv'])];
const isTypeSupported = type => SUPPORTED_TYPES.indexOf(type) !== -1; const isTypeSupported = type => SUPPORTED_TYPES.indexOf(type) !== -1;
@ -51,7 +52,7 @@ const Video = React.memo(({
<> <>
<Touchable <Touchable
onPress={onPress} onPress={onPress}
style={styles.button} style={[styles.button, isTablet && sharedStyles.tabletContent]}
background={Touchable.Ripple('#fff')} background={Touchable.Ripple('#fff')}
> >
<CustomIcon <CustomIcon

View File

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

View File

@ -279,6 +279,7 @@ export default {
pinned: 'pinned', pinned: 'pinned',
Pinned: 'Pinned', Pinned: 'Pinned',
Please_enter_your_password: 'Please enter your password', Please_enter_your_password: 'Please enter your password',
Preferences: 'Preferences',
Preferences_saved: 'Preferences saved!', Preferences_saved: 'Preferences saved!',
Privacy_Policy: ' Privacy Policy', Privacy_Policy: ' Privacy Policy',
Private_Channel: 'Private Channel', Private_Channel: 'Private Channel',
@ -441,5 +442,19 @@ export default {
Version_no: 'Version: {{version}}', Version_no: 'Version: {{version}}',
You_will_not_be_able_to_recover_this_message: 'You will not be able to recover this message!', You_will_not_be_able_to_recover_this_message: 'You will not be able to recover this message!',
Change_Language: 'Change Language', 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: 'fixada',
Pinned: 'Mensagens Fixadas', Pinned: 'Mensagens Fixadas',
Please_enter_your_password: 'Por favor, digite sua senha', Please_enter_your_password: 'Por favor, digite sua senha',
Preferences: 'Preferências',
Preferences_saved: 'Preferências salvas!', Preferences_saved: 'Preferências salvas!',
Privacy_Policy: ' Política de Privacidade', Privacy_Policy: ' Política de Privacidade',
Private_Channel: 'Canal Privado', Private_Channel: 'Canal Privado',
@ -392,5 +393,20 @@ export default {
you: 'você', you: 'você',
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_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 React from 'react';
import { View, Linking, BackHandler } from 'react-native';
import { createAppContainer, createSwitchNavigator } from 'react-navigation'; import { createAppContainer, createSwitchNavigator } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack'; import { createStackNavigator } from 'react-navigation-stack';
import { createDrawerNavigator } from 'react-navigation-drawer'; import { createDrawerNavigator } from 'react-navigation-drawer';
import { Provider } from 'react-redux'; import { Provider } from 'react-redux';
import { Linking } from 'react-native';
import PropTypes from 'prop-types'; 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 { appInit } from './actions';
import { deepLinkingOpen } from './actions/deepLinking'; import { deepLinkingOpen } from './actions/deepLinking';
import Navigation from './lib/Navigation'; import Navigation from './lib/Navigation';
@ -18,7 +21,14 @@ import { defaultHeader, onNavigationStateChange } from './utils/navigation';
import { loggerConfig, analytics } from './utils/log'; import { loggerConfig, analytics } from './utils/log';
import Toast from './containers/Toast'; import Toast from './containers/Toast';
import RocketChat from './lib/rocketchat'; 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) { if (isIOS) {
const RNScreens = require('react-native-screens'); const RNScreens = require('react-native-screens');
@ -84,14 +94,26 @@ const OutsideStackModal = createStackNavigator({
headerMode: 'none' 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 // Inside
const ChatsStack = createStackNavigator({ const ChatsStack = createStackNavigator({
RoomsListView: { RoomsListView: {
getScreen: () => require('./views/RoomsListView').default getScreen: () => require('./views/RoomsListView').default
}, },
RoomView: {
getScreen: () => require('./views/RoomView').default
},
RoomActionsView: { RoomActionsView: {
getScreen: () => require('./views/RoomActionsView').default getScreen: () => require('./views/RoomActionsView').default
}, },
@ -110,34 +132,33 @@ const ChatsStack = createStackNavigator({
SelectedUsersView: { SelectedUsersView: {
getScreen: () => require('./views/SelectedUsersView').default getScreen: () => require('./views/SelectedUsersView').default
}, },
ThreadMessagesView: {
getScreen: () => require('./views/ThreadMessagesView').default
},
MessagesView: { MessagesView: {
getScreen: () => require('./views/MessagesView').default getScreen: () => require('./views/MessagesView').default
}, },
AutoTranslateView: { AutoTranslateView: {
getScreen: () => require('./views/AutoTranslateView').default getScreen: () => require('./views/AutoTranslateView').default
}, },
ReadReceiptsView: {
getScreen: () => require('./views/ReadReceiptView').default
},
DirectoryView: { DirectoryView: {
getScreen: () => require('./views/DirectoryView').default getScreen: () => require('./views/DirectoryView').default
}, },
TableView: {
getScreen: () => require('./views/TableView').default
},
NotificationPrefView: { NotificationPrefView: {
getScreen: () => require('./views/NotificationPreferencesView').default getScreen: () => require('./views/NotificationPreferencesView').default
} },
...RoomRoutes
}, {
defaultNavigationOptions: defaultHeader
});
// Inside
const RoomStack = createStackNavigator({
...RoomRoutes
}, { }, {
defaultNavigationOptions: defaultHeader defaultNavigationOptions: defaultHeader
}); });
ChatsStack.navigationOptions = ({ navigation }) => { ChatsStack.navigationOptions = ({ navigation }) => {
let drawerLockMode = 'unlocked'; let drawerLockMode = 'unlocked';
if (navigation.state.index > 0) { if (navigation.state.index > 0 || isSplited()) {
drawerLockMode = 'locked-closed'; drawerLockMode = 'locked-closed';
} }
return { return {
@ -238,22 +259,188 @@ class CustomInsideStack extends React.Component {
static router = InsideStackModal.router; static router = InsideStackModal.router;
static propTypes = { static propTypes = {
navigation: PropTypes.object navigation: PropTypes.object,
screenProps: PropTypes.object
} }
render() { render() {
const { navigation } = this.props; const { navigation, screenProps } = this.props;
return ( return (
<> <>
<InsideStackModal navigation={navigation} /> <InsideStackModal navigation={navigation} screenProps={screenProps} />
<NotificationBadge navigation={navigation} /> { !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 /> <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, OutsideStack: OutsideStackModal,
InsideStack: CustomInsideStack, 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 { export default class Root extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.init(); this.init();
this.initCrashReport(); this.initCrashReport();
this.state = {
split: false,
inside: false,
showModal: false
};
if (isTablet) {
this.initTablet();
}
} }
componentDidMount() { componentDidMount() {
@ -285,8 +486,23 @@ export default class Root extends React.Component {
}, 5000); }, 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() { componentWillUnmount() {
clearTimeout(this.listenerTimeout); clearTimeout(this.listenerTimeout);
if (this.onKeyCommands && this.onKeyCommands.remove) {
this.onKeyCommands.remove();
}
} }
init = async() => { 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 = () => { initCrashReport = () => {
RocketChat.getAllowCrashReport() RocketChat.getAllowCrashReport()
.then((allowCrashReport) => { .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() { 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 ( return (
<Provider store={store}> <Provider store={store}>
<App {content}
ref={(navigatorRef) => {
Navigation.setTopLevelNavigator(navigatorRef);
}}
onNavigationStateChange={onNavigationStateChange}
/>
</Provider> </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 { responsive } from 'react-native-responsive-ui';
import Touchable from 'react-native-platform-touchable'; 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 { CustomIcon } from '../../lib/Icons';
import { COLOR_BACKGROUND_NOTIFICATION, COLOR_SEPARATOR, COLOR_TEXT } from '../../constants/colors'; import { COLOR_BACKGROUND_NOTIFICATION, COLOR_SEPARATOR, COLOR_TEXT } from '../../constants/colors';
import Avatar from '../../containers/Avatar'; import Avatar from '../../containers/Avatar';
@ -158,7 +158,7 @@ class NotificationBadge extends React.Component {
} }
goToRoom = async() => { goToRoom = async() => {
const { notification: { payload }, navigation } = this.props; const { notification: { payload }, navigation, baseUrl } = this.props;
const { rid, type, prid } = payload; const { rid, type, prid } = payload;
if (!rid) { if (!rid) {
return; return;
@ -166,7 +166,7 @@ class NotificationBadge extends React.Component {
const name = type === 'd' ? payload.sender.username : payload.name; const name = type === 'd' ? payload.sender.username : payload.name;
await navigation.navigate('RoomsListView'); await navigation.navigate('RoomsListView');
navigation.navigate('RoomView', { navigation.navigate('RoomView', {
rid, name, t: type, prid rid, name, t: type, prid, baseUrl
}); });
this.hide(); this.hide();
} }
@ -185,7 +185,7 @@ class NotificationBadge extends React.Component {
if (portrait) { if (portrait) {
top = isNotch ? 45 : 20; top = isNotch ? 45 : 20;
} else { } else {
top = 0; top = isTablet ? 20 : 0;
} }
} }

View File

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

View File

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

View File

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

View File

@ -7,24 +7,30 @@ import RocketChat from '../lib/rocketchat';
import database from '../lib/database'; import database from '../lib/database';
import log from '../utils/log'; 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('RoomsListView');
Navigation.navigate('RoomView', { Navigation.navigate('RoomView', {
rid, name, t: 'd', message rid, name, fname, t: 'd', message
}); });
}; };
const handleReplyBroadcast = function* handleReplyBroadcast({ message }) { const handleReplyBroadcast = function* handleReplyBroadcast({ message }) {
try { try {
const db = database.active; const db = database.active;
const { username } = message.u; const { username, name } = message.u;
const subsCollection = db.collections.get('subscriptions'); const subsCollection = db.collections.get('subscriptions');
const subscriptions = yield subsCollection.query(Q.where('name', username)).fetch(); const subscriptions = yield subsCollection.query(Q.where('name', username)).fetch();
if (subscriptions.length) { if (subscriptions.length) {
yield goRoom({ rid: subscriptions[0].rid, name: username, message }); yield goRoom({
rid: subscriptions[0].rid, name: username, fname: name, message
});
} else { } else {
const room = yield RocketChat.createDirectMessage(username); 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) { } catch (e) {
log(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 { Platform } from 'react-native';
import DeviceInfo from 'react-native-device-info'; 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']; const NOTCH_DEVICES = ['iPhone X', 'iPhone XS', 'iPhone XS Max', 'iPhone XR'];
export const isNotch = NOTCH_DEVICES.includes(DeviceInfo.getModel()); export const isNotch = NOTCH_DEVICES.includes(DeviceInfo.getModel());
@ -9,3 +11,13 @@ export const isAndroid = !isIOS;
export const getReadableVersion = DeviceInfo.getReadableVersion(); export const getReadableVersion = DeviceInfo.getReadableVersion();
export const getBundleId = DeviceInfo.getBundleId(); export const getBundleId = DeviceInfo.getBundleId();
export const getDeviceModel = DeviceInfo.getModel(); 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 { Dimensions } from 'react-native';
import { isTablet } from './deviceInfo';
const { width, height } = Dimensions.get('window'); const { width, height } = Dimensions.get('window');
const guidelineBaseWidth = 375; const guidelineBaseWidth = isTablet ? 600 : 375;
const guidelineBaseHeight = 667; const guidelineBaseHeight = isTablet ? 800 : 667;
const scale = size => (width / guidelineBaseWidth) * size; const scale = size => (width / guidelineBaseWidth) * size;
const verticalScale = size => (height / guidelineBaseHeight) * size; const verticalScale = size => (height / guidelineBaseHeight) * size;

View File

@ -7,13 +7,14 @@ import { isAndroid } from '../utils/deviceInfo';
const styles = StyleSheet.create({ const styles = StyleSheet.create({
image: { image: {
width: '100%', width: '100%',
height: '100%' height: '100%',
backgroundColor: 'white'
} }
}); });
export default React.memo(() => ( export default React.memo(() => (
<> <>
<StatusBar /> <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 { CustomIcon } from '../../lib/Icons';
import StatusBar from '../../containers/StatusBar'; import StatusBar from '../../containers/StatusBar';
import RCActivityIndicator from '../../containers/ActivityIndicator'; import RCActivityIndicator from '../../containers/ActivityIndicator';
import { CloseModalButton } from '../../containers/HeaderButton';
import debounce from '../../utils/debounce'; import debounce from '../../utils/debounce';
import log from '../../utils/log'; import log from '../../utils/log';
import Options from './Options'; import Options from './Options';
import styles from './styles'; import styles from './styles';
class DirectoryView extends React.Component { class DirectoryView extends React.Component {
static navigationOptions = () => ({ static navigationOptions = ({ navigation, screenProps }) => {
title: I18n.t('Directory') const options = {
}) title: I18n.t('Directory')
};
if (screenProps.split) {
options.headerLeft = <CloseModalButton navigation={navigation} testID='directory-view-close' />;
}
return options;
}
static propTypes = { static propTypes = {
navigation: PropTypes.object, navigation: PropTypes.object,
@ -56,16 +63,6 @@ class DirectoryView extends React.Component {
this.setState({ text }); 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 // eslint-disable-next-line react/sort-comp
load = debounce(async({ newSearch = false }) => { load = debounce(async({ newSearch = false }) => {
if (newSearch) { if (newSearch) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,24 +1,10 @@
import React from 'react'; import React from 'react';
import { StyleSheet } from 'react-native';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { CustomHeaderButtons, Item } from '../../../containers/HeaderButton'; import { CustomHeaderButtons, Item } from '../../../containers/HeaderButton';
import database from '../../../lib/database'; 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 { class RightButtonsContainer extends React.PureComponent {
static propTypes = { static propTypes = {
userId: PropTypes.string, userId: PropTypes.string,
@ -27,8 +13,7 @@ class RightButtonsContainer extends React.PureComponent {
t: PropTypes.string, t: PropTypes.string,
tmid: PropTypes.string, tmid: PropTypes.string,
navigation: PropTypes.object, navigation: PropTypes.object,
toggleFollowThread: PropTypes.func, toggleFollowThread: PropTypes.func
room: PropTypes.object
}; };
constructor(props) { constructor(props) {
@ -75,13 +60,6 @@ class RightButtonsContainer extends React.PureComponent {
navigation.navigate('ThreadMessagesView', { rid, t }); navigation.navigate('ThreadMessagesView', { rid, t });
} }
goRoomActionsView = () => {
const {
rid, t, navigation, room
} = this.props;
navigation.navigate('RoomActionsView', { rid, t, room });
}
toggleFollowThread = () => { toggleFollowThread = () => {
const { isFollowingThread } = this.state; const { isFollowingThread } = this.state;
const { toggleFollowThread } = this.props; const { toggleFollowThread } = this.props;
@ -116,16 +94,8 @@ class RightButtonsContainer extends React.PureComponent {
iconName='thread' iconName='thread'
onPress={this.goThreadsView} onPress={this.goThreadsView}
testID='room-view-header-threads' testID='room-view-header-threads'
buttonStyle={styles.thread}
/> />
) : null} ) : null}
<Item
title='more'
iconName='menu'
onPress={this.goRoomActionsView}
testID='room-view-header-actions'
buttonStyle={styles.more}
/>
</CustomHeaderButtons> </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 Header from './Header';
import RightButtons from './RightButtons'; import RightButtons from './RightButtons';
import RoomHeaderLeft from './RoomHeaderLeft';
class RoomHeaderView extends Component { class RoomHeaderView extends Component {
static propTypes = { static propTypes = {
@ -17,13 +18,13 @@ class RoomHeaderView extends Component {
window: PropTypes.object, window: PropTypes.object,
status: PropTypes.string, status: PropTypes.string,
connecting: PropTypes.bool, connecting: PropTypes.bool,
widthOffset: PropTypes.number widthOffset: PropTypes.number,
goRoomActionsView: PropTypes.func
}; };
shouldComponentUpdate(nextProps) { shouldComponentUpdate(nextProps) {
const { usersTyping } = this.props;
const { const {
type, title, status, window, connecting type, title, status, window, connecting, goRoomActionsView, usersTyping
} = this.props; } = this.props;
if (nextProps.type !== type) { if (nextProps.type !== type) {
return true; return true;
@ -46,12 +47,15 @@ class RoomHeaderView extends Component {
if (!equal(nextProps.usersTyping, usersTyping)) { if (!equal(nextProps.usersTyping, usersTyping)) {
return true; return true;
} }
if (nextProps.goRoomActionsView !== goRoomActionsView) {
return true;
}
return false; return false;
} }
render() { render() {
const { const {
window, title, type, prid, tmid, widthOffset, status = 'offline', connecting, usersTyping window, title, type, prid, tmid, widthOffset, status = 'offline', connecting, usersTyping, goRoomActionsView
} = this.props; } = this.props;
return ( return (
@ -65,6 +69,7 @@ class RoomHeaderView extends Component {
height={window.height} height={window.height}
usersTyping={usersTyping} usersTyping={usersTyping}
widthOffset={widthOffset} widthOffset={widthOffset}
goRoomActionsView={goRoomActionsView}
connecting={connecting} connecting={connecting}
/> />
); );
@ -91,4 +96,4 @@ const mapStateToProps = (state, ownProps) => {
export default responsive(connect(mapStateToProps)(RoomHeaderView)); 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, rid: PropTypes.string,
t: PropTypes.string, t: PropTypes.string,
tmid: PropTypes.string, tmid: PropTypes.string,
listRef: PropTypes.func,
animated: PropTypes.bool animated: PropTypes.bool
}; };
@ -63,29 +64,31 @@ export class List extends React.Component {
this.messagesObservable = db.collections this.messagesObservable = db.collections
.get('thread_messages') .get('thread_messages')
.query(Q.where('rid', tmid)) .query(Q.where('rid', tmid))
.observeWithColumns(['_updated_at']); .observe();
} else { } else if (rid) {
this.messagesObservable = db.collections this.messagesObservable = db.collections
.get('messages') .get('messages')
.query(Q.where('rid', rid)) .query(Q.where('rid', rid))
.observeWithColumns(['_updated_at']); .observe();
} }
this.unsubscribeMessages(); if (rid) {
this.messagesSubscription = this.messagesObservable this.unsubscribeMessages();
.subscribe((data) => { this.messagesSubscription = this.messagesObservable
this.interaction = InteractionManager.runAfterInteractions(() => { .subscribe((data) => {
if (tmid) { this.interaction = InteractionManager.runAfterInteractions(() => {
data = [this.thread, ...data]; if (tmid) {
} data = [this.thread, ...data];
const messages = orderBy(data, ['ts'], ['desc']); }
if (this.mounted) { const messages = orderBy(data, ['ts'], ['desc']);
this.setState({ messages }, () => this.debouncedUpdate()); if (this.mounted) {
} else { this.setState({ messages }, () => this.update());
this.state.messages = messages; } else {
} this.state.messages = messages;
}
});
}); });
}); }
} }
// this.state.loading works for this.onEndReached and RoomView.init // 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) { if (this.onEndReached && this.onEndReached.stop) {
this.onEndReached.stop(); this.onEndReached.stop();
} }
if (this.debouncedUpdate && this.debouncedUpdate.stop) {
this.debouncedUpdate.stop();
}
console.countReset(`${ this.constructor.name }.render calls`); console.countReset(`${ this.constructor.name }.render calls`);
} }
@ -155,20 +155,24 @@ export class List extends React.Component {
this.forceUpdate(); this.forceUpdate();
}; };
// eslint-disable-next-line react/sort-comp
debouncedUpdate = debounce(() => {
this.update();
}, 300)
unsubscribeMessages = () => { unsubscribeMessages = () => {
if (this.messagesSubscription && this.messagesSubscription.unsubscribe) { if (this.messagesSubscription && this.messagesSubscription.unsubscribe) {
this.messagesSubscription.unsubscribe(); this.messagesSubscription.unsubscribe();
} }
} }
getLastMessage = () => {
const { messages } = this.state;
if (messages.length > 0) {
return messages[0];
}
return null;
}
renderFooter = () => { renderFooter = () => {
const { loading } = this.state; const { loading } = this.state;
if (loading) { const { rid } = this.props;
if (loading && rid) {
return <ActivityIndicator style={styles.loading} />; return <ActivityIndicator style={styles.loading} />;
} }
return null; return null;
@ -182,13 +186,14 @@ export class List extends React.Component {
render() { render() {
console.count(`${ this.constructor.name }.render calls`); console.count(`${ this.constructor.name }.render calls`);
const { rid, listRef } = this.props;
const { messages } = this.state; const { messages } = this.state;
return ( return (
<> <>
<EmptyRoom length={messages.length} mounted={this.mounted} /> <EmptyRoom rid={rid} length={messages.length} mounted={this.mounted} />
<FlatList <FlatList
testID='room-view-messages' testID='room-view-messages'
ref={ref => this.list = ref} ref={listRef}
keyExtractor={item => item.id} keyExtractor={item => item.id}
data={messages} data={messages}
extraData={this.state} extraData={this.state}

View File

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

View File

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

View File

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

View File

@ -6,6 +6,9 @@ import {
toggleServerDropdown, closeServerDropdown, closeSortDropdown, setSearch as setSearchAction toggleServerDropdown, closeServerDropdown, closeSortDropdown, setSearch as setSearchAction
} from '../../../actions/rooms'; } from '../../../actions/rooms';
import Header from './Header'; import Header from './Header';
import EventEmitter from '../../../utils/events';
import { KEY_COMMAND, handleCommandOpenServerDropdown } from '../../../commands';
import { isTablet } from '../../../utils/deviceInfo';
class RoomsListHeaderView extends PureComponent { class RoomsListHeaderView extends PureComponent {
static propTypes = { static propTypes = {
@ -21,6 +24,24 @@ class RoomsListHeaderView extends PureComponent {
setSearch: PropTypes.func 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) => { onSearchChangeText = (text) => {
const { setSearch } = this.props; const { setSearch } = this.props;
setSearch(text.trim()); setSearch(text.trim());

View File

@ -4,14 +4,15 @@ import PropTypes from 'prop-types';
import SearchBox from '../../../containers/SearchBox'; import SearchBox from '../../../containers/SearchBox';
import { isIOS } from '../../../utils/deviceInfo'; import { isIOS } from '../../../utils/deviceInfo';
const SearchBar = React.memo(({ onChangeSearchText }) => { const SearchBar = React.memo(({ onChangeSearchText, inputRef }) => {
if (isIOS) { 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; return null;
}); });
SearchBar.propTypes = { SearchBar.propTypes = {
inputRef: PropTypes.func,
onChangeSearchText: PropTypes.func onChangeSearchText: PropTypes.func
}; };

View File

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

View File

@ -18,6 +18,9 @@ import I18n from '../../i18n';
import EventEmitter from '../../utils/events'; import EventEmitter from '../../utils/events';
import Check from '../../containers/Check'; import Check from '../../containers/Check';
import database from '../../lib/database'; 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 ROW_HEIGHT = 68;
const ANIMATION_DURATION = 200; const ANIMATION_DURATION = 200;
@ -26,6 +29,7 @@ class ServerDropdown extends Component {
static propTypes = { static propTypes = {
navigation: PropTypes.object, navigation: PropTypes.object,
closeServerDropdown: PropTypes.bool, closeServerDropdown: PropTypes.bool,
split: PropTypes.bool,
server: PropTypes.string, server: PropTypes.string,
toggleServerDropdown: PropTypes.func, toggleServerDropdown: PropTypes.func,
selectServerRequest: PropTypes.func, selectServerRequest: PropTypes.func,
@ -58,6 +62,9 @@ class ServerDropdown extends Component {
useNativeDriver: true useNativeDriver: true
} }
).start(); ).start();
if (isTablet) {
EventEmitter.addEventListener(KEY_COMMAND, this.handleCommands);
}
} }
shouldComponentUpdate(nextProps, nextState) { shouldComponentUpdate(nextProps, nextState) {
@ -90,6 +97,9 @@ class ServerDropdown extends Component {
if (this.subscription && this.subscription.unsubscribe) { if (this.subscription && this.subscription.unsubscribe) {
this.subscription.unsubscribe(); this.subscription.unsubscribe();
} }
if (isTablet) {
EventEmitter.removeListener(KEY_COMMAND, this.handleCommands);
}
} }
close = () => { close = () => {
@ -116,12 +126,15 @@ class ServerDropdown extends Component {
select = async(server) => { select = async(server) => {
const { const {
server: currentServer, selectServerRequest, appStart server: currentServer, selectServerRequest, appStart, navigation, split
} = this.props; } = this.props;
this.close(); this.close();
if (currentServer !== server) { if (currentServer !== server) {
const userId = await RNUserDefaults.get(`${ RocketChat.TOKEN_KEY }-${ server }`); const userId = await RNUserDefaults.get(`${ RocketChat.TOKEN_KEY }-${ server }`);
if (split) {
navigation.navigate('RoomView');
}
if (!userId) { if (!userId) {
appStart(); appStart();
this.newServerTimeout = setTimeout(() => { 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} />; renderSeparator = () => <View style={styles.serverSeparator} />;
renderServer = ({ item }) => { renderServer = ({ item }) => {
@ -201,6 +226,7 @@ class ServerDropdown extends Component {
keyExtractor={item => item.id} keyExtractor={item => item.id}
renderItem={this.renderServer} renderItem={this.renderServer}
ItemSeparatorComponent={this.renderSeparator} ItemSeparatorComponent={this.renderSeparator}
keyboardShouldPersistTaps='always'
/> />
</Animated.View> </Animated.View>
] ]
@ -219,4 +245,4 @@ const mapDispatchToProps = dispatch => ({
appStart: () => dispatch(appStartAction('outside')) 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, BackHandler,
ActivityIndicator, ActivityIndicator,
Text, Text,
ScrollView,
Keyboard, Keyboard,
Dimensions Dimensions
} from 'react-native'; } from 'react-native';
@ -33,7 +32,7 @@ import {
} from '../../actions/rooms'; } from '../../actions/rooms';
import { appStart as appStartAction } from '../../actions'; import { appStart as appStartAction } from '../../actions';
import debounce from '../../utils/debounce'; import debounce from '../../utils/debounce';
import { isIOS, isAndroid } from '../../utils/deviceInfo'; import { isIOS, isAndroid, isTablet } from '../../utils/deviceInfo';
import RoomsListHeaderView from './Header'; import RoomsListHeaderView from './Header';
import { import {
DrawerButton, DrawerButton,
@ -44,8 +43,29 @@ import StatusBar from '../../containers/StatusBar';
import ListHeader from './ListHeader'; import ListHeader from './ListHeader';
import { selectServerRequest as selectServerRequestAction } from '../../actions/server'; import { selectServerRequest as selectServerRequestAction } from '../../actions/server';
import { animateNextTransition } from '../../utils/layoutAnimation'; 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 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 = [ const shouldUpdateProps = [
'searchText', 'searchText',
@ -58,7 +78,8 @@ const shouldUpdateProps = [
'showUnread', 'showUnread',
'useRealName', 'useRealName',
'StoreLastMessage', 'StoreLastMessage',
'appState' 'appState',
'split'
]; ];
const getItemLayout = (data, index) => ({ const getItemLayout = (data, index) => ({
length: ROW_HEIGHT, length: ROW_HEIGHT,
@ -140,7 +161,8 @@ class RoomsListView extends React.Component {
closeSearchHeader: PropTypes.func, closeSearchHeader: PropTypes.func,
appStart: PropTypes.func, appStart: PropTypes.func,
roomsRequest: PropTypes.func, roomsRequest: PropTypes.func,
closeServerDropdown: PropTypes.func closeServerDropdown: PropTypes.func,
split: PropTypes.bool
}; };
constructor(props) { constructor(props) {
@ -148,6 +170,7 @@ class RoomsListView extends React.Component {
console.time(`${ this.constructor.name } init`); console.time(`${ this.constructor.name } init`);
console.time(`${ this.constructor.name } mount`); console.time(`${ this.constructor.name } mount`);
this.gotSubscriptions = false;
const { width } = Dimensions.get('window'); const { width } = Dimensions.get('window');
this.state = { this.state = {
searching: false, searching: false,
@ -155,16 +178,24 @@ class RoomsListView extends React.Component {
loading: true, loading: true,
allChats: [], allChats: [],
chats: [], chats: [],
unread: [],
favorites: [],
discussions: [],
channels: [],
privateGroup: [],
direct: [],
width 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(); 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) // Check if there were changes while not focused (it's set on sCU)
if (this.shouldUpdate) { if (this.shouldUpdate) {
// animateNextTransition(); // animateNextTransition();
@ -172,43 +203,30 @@ class RoomsListView extends React.Component {
this.shouldUpdate = false; this.shouldUpdate = false;
} }
}); });
this.didFocusListener = props.navigation.addListener('didFocus', () => { this.didFocusListener = navigation.addListener('didFocus', () => {
BackHandler.addEventListener( this.backHandler = BackHandler.addEventListener('hardwareBackPress', this.handleBackPress);
'hardwareBackPress',
this.handleBackPress
);
}); });
this.willBlurListener = props.navigation.addListener('willBlur', () => { this.willBlurListener = navigation.addListener('willBlur', () => {
props.closeServerDropdown(); closeServerDropdown();
BackHandler.addEventListener( this.backHandler.remove();
'hardwareBackPress',
this.handleBackPress
);
}); });
}
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`); console.timeEnd(`${ this.constructor.name } mount`);
} }
componentWillReceiveProps(nextProps) { componentWillReceiveProps(nextProps) {
const { loadingServer, searchText } = this.props; const { loadingServer, searchText, server } = this.props;
if (nextProps.server && loadingServer !== nextProps.loadingServer) { if (nextProps.server && loadingServer !== nextProps.loadingServer) {
if (nextProps.loadingServer) { if (nextProps.loadingServer) {
this.internalSetState({ loading: true }); this.setState({ loading: true });
} else { } else {
this.getSubscriptions(); this.getSubscriptions();
} }
} else if (searchText !== nextProps.searchText) { }
if (server && server !== nextProps.server) {
this.gotSubscriptions = false;
}
if (searchText !== nextProps.searchText) {
this.search(nextProps.searchText); this.search(nextProps.searchText);
} }
} }
@ -278,7 +296,7 @@ class RoomsListView extends React.Component {
&& prevProps.showUnread === showUnread && prevProps.showUnread === showUnread
) )
) { ) {
this.getSubscriptions(); this.getSubscriptions(true);
} else if ( } else if (
appState === 'foreground' appState === 'foreground'
&& appState !== prevProps.appState && appState !== prevProps.appState
@ -288,9 +306,6 @@ class RoomsListView extends React.Component {
} }
componentWillUnmount() { componentWillUnmount() {
if (this.getSubscriptions && this.getSubscriptions.stop) {
this.getSubscriptions.stop();
}
if (this.querySubscription && this.querySubscription.unsubscribe) { if (this.querySubscription && this.querySubscription.unsubscribe) {
this.querySubscription.unsubscribe(); this.querySubscription.unsubscribe();
} }
@ -303,6 +318,9 @@ class RoomsListView extends React.Component {
if (this.willBlurListener && this.willBlurListener.remove) { if (this.willBlurListener && this.willBlurListener.remove) {
this.willBlurListener.remove(); this.willBlurListener.remove();
} }
if (isTablet) {
EventEmitter.removeListener(KEY_COMMAND, this.handleCommands);
}
Dimensions.removeEventListener('change', this.onDimensionsChange); Dimensions.removeEventListener('change', this.onDimensionsChange);
console.countReset(`${ this.constructor.name }.render calls`); console.countReset(`${ this.constructor.name }.render calls`);
} }
@ -318,11 +336,28 @@ class RoomsListView extends React.Component {
this.setState(...args); 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) { if (this.querySubscription && this.querySubscription.unsubscribe) {
this.querySubscription.unsubscribe(); this.querySubscription.unsubscribe();
} }
this.setState({ loading: true });
const { const {
sortBy, sortBy,
showUnread, showUnread,
@ -341,13 +376,8 @@ class RoomsListView extends React.Component {
.observeWithColumns(['room_updated_at', 'unread', 'alert', 'user_mentions', 'f', 't']); .observeWithColumns(['room_updated_at', 'unread', 'alert', 'user_mentions', 'f', 't']);
this.querySubscription = observable.subscribe((data) => { this.querySubscription = observable.subscribe((data) => {
let tempChats = [];
let chats = []; let chats = [];
let unread = [];
let favorites = [];
let discussions = [];
let channels = [];
let privateGroup = [];
let direct = [];
if (sortBy === 'alphabetical') { if (sortBy === 'alphabetical') {
chats = orderBy(data, ['name'], ['asc']); chats = orderBy(data, ['name'], ['asc']);
} else { } else {
@ -372,41 +402,43 @@ class RoomsListView extends React.Component {
// unread // unread
if (showUnread) { if (showUnread) {
unread = chats.filter(s => (s.unread > 0 || s.alert) && !s.hideUnreadStatus); const unread = chats.filter(s => (s.unread > 0 || s.alert) && !s.hideUnreadStatus);
} else { tempChats = this.addRoomsGroup(unread, UNREAD_HEADER, tempChats);
unread = [];
} }
// favorites // favorites
if (showFavorites) { if (showFavorites) {
favorites = chats.filter(s => s.f); const favorites = chats.filter(s => s.f);
} else { tempChats = this.addRoomsGroup(favorites, FAVORITES_HEADER, tempChats);
favorites = [];
} }
// type // type
if (groupByType) { if (groupByType) {
discussions = chats.filter(s => s.prid); const discussions = chats.filter(s => s.prid);
channels = chats.filter(s => s.t === 'c' && !s.prid); const channels = chats.filter(s => s.t === 'c' && !s.prid);
privateGroup = chats.filter(s => s.t === 'p' && !s.prid); const privateGroup = chats.filter(s => s.t === 'p' && !s.prid);
direct = chats.filter(s => s.t === 'd' && !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) { } else if (showUnread) {
chats = chats.filter(s => (!s.unread && !s.alert) || s.hideUnreadStatus); 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({ this.internalSetState({
chats: tempChats,
allChats, allChats,
chats,
unread,
favorites,
discussions,
channels,
privateGroup,
direct,
loading: false loading: false
}); });
}); });
}, 300, true); }
initSearchingAndroid = () => { initSearchingAndroid = () => {
const { openSearchHeader, navigation } = this.props; const { openSearchHeader, navigation } = this.props;
@ -422,8 +454,8 @@ class RoomsListView extends React.Component {
navigation.setParams({ searching: false }); navigation.setParams({ searching: false });
closeSearchHeader(); closeSearchHeader();
this.internalSetState({ search: [] }); this.internalSetState({ search: [] });
Keyboard.dismiss();
} }
Keyboard.dismiss();
}; };
handleBackPress = () => { handleBackPress = () => {
@ -453,6 +485,7 @@ class RoomsListView extends React.Component {
goRoom = (item) => { goRoom = (item) => {
this.cancelSearchingAndroid(); this.cancelSearchingAndroid();
const { navigation } = this.props; const { navigation } = this.props;
this.item = item;
navigation.navigate('RoomView', { navigation.navigate('RoomView', {
rid: item.rid, rid: item.rid,
name: this.getRoomTitle(item), name: this.getRoomTitle(item),
@ -569,6 +602,70 @@ class RoomsListView extends React.Component {
navigation.navigate('DirectoryView'); 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); getScrollRef = ref => (this.scroll = ref);
renderListHeader = () => { renderListHeader = () => {
@ -576,6 +673,7 @@ class RoomsListView extends React.Component {
const { sortBy } = this.props; const { sortBy } = this.props;
return ( return (
<ListHeader <ListHeader
inputRef={(ref) => { this.inputRef = ref; }}
searchLength={search.length} searchLength={search.length}
sortBy={sortBy} sortBy={sortBy}
onChangeSearchText={this.search} onChangeSearchText={this.search}
@ -592,13 +690,18 @@ class RoomsListView extends React.Component {
}; };
renderItem = ({ item }) => { renderItem = ({ item }) => {
if (item.separator) {
return this.renderSectionHeader(item.rid);
}
const { width } = this.state; const { width } = this.state;
const { const {
userId, userId,
username, username,
token, token,
baseUrl, baseUrl,
StoreLastMessage StoreLastMessage,
split
} = this.props; } = this.props;
const id = item.rid.replace(userId, '').trim(); const id = item.rid.replace(userId, '').trim();
@ -626,7 +729,7 @@ class RoomsListView extends React.Component {
showLastMessage={StoreLastMessage} showLastMessage={StoreLastMessage}
onPress={() => this._onPressItem(item)} onPress={() => this._onPressItem(item)}
testID={`rooms-list-view-item-${ item.name }`} testID={`rooms-list-view-item-${ item.name }`}
width={width} width={split ? MAX_SIDEBAR_WIDTH : width}
toggleFav={this.toggleFav} toggleFav={this.toggleFav}
toggleRead={this.toggleRead} toggleRead={this.toggleRead}
hideChannel={this.hideChannel} hideChannel={this.hideChannel}
@ -640,129 +743,29 @@ class RoomsListView extends React.Component {
</View> </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 = () => { renderScroll = () => {
const { loading } = this.state; const { loading, chats, search } = this.state;
if (loading) { if (loading) {
return <ActivityIndicator style={styles.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 ( return (
<ScrollView <FlatList
ref={this.getScrollRef} ref={this.getScrollRef}
data={search.length ? search : chats}
extraData={search.length ? search : chats}
contentOffset={isIOS ? { x: 0, y: SCROLL_OFFSET } : {}} contentOffset={isIOS ? { x: 0, y: SCROLL_OFFSET } : {}}
keyExtractor={keyExtractor}
style={styles.list}
renderItem={this.renderItem}
ListHeaderComponent={this.renderListHeader}
getItemLayout={getItemLayout}
removeClippedSubviews={isIOS}
keyboardShouldPersistTaps='always' keyboardShouldPersistTaps='always'
testID='rooms-list-view-list' initialNumToRender={INITIAL_NUM_TO_RENDER}
> windowSize={9}
{this.renderListHeader()} />
{this.renderList()}
</ScrollView>
); );
}; };
@ -829,4 +832,4 @@ const mapDispatchToProps = dispatch => ({
closeServerDropdown: () => dispatch(closeServerDropdownAction()) 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 RocketChat from '../lib/rocketchat';
import StatusBar from '../containers/StatusBar'; import StatusBar from '../containers/StatusBar';
import log from '../utils/log'; import log from '../utils/log';
import { isTablet } from '../utils/deviceInfo';
const styles = StyleSheet.create({ const styles = StyleSheet.create({
loginTitle: { loginTitle: {
@ -49,7 +50,9 @@ class SetUsernameView extends React.Component {
}; };
const { server } = this.props; const { server } = this.props;
props.navigation.setParams({ title: server }); props.navigation.setParams({ title: server });
Orientation.lockToPortrait(); if (!isTablet) {
Orientation.lockToPortrait();
}
} }
async componentDidMount() { async componentDidMount() {

View File

@ -5,17 +5,20 @@ import {
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { logout as logoutAction } from '../../actions/login';
import { toggleMarkdown as toggleMarkdownAction } from '../../actions/markdown'; import { toggleMarkdown as toggleMarkdownAction } from '../../actions/markdown';
import { toggleCrashReport as toggleCrashReportAction } from '../../actions/crashReport'; import { toggleCrashReport as toggleCrashReportAction } from '../../actions/crashReport';
import { SWITCH_TRACK_COLOR } from '../../constants/colors'; import { SWITCH_TRACK_COLOR, COLOR_DANGER } from '../../constants/colors';
import { DrawerButton } from '../../containers/HeaderButton'; import { DrawerButton, CloseModalButton } from '../../containers/HeaderButton';
import StatusBar from '../../containers/StatusBar'; import StatusBar from '../../containers/StatusBar';
import ListItem from '../../containers/ListItem'; import ListItem from '../../containers/ListItem';
import { DisclosureImage } from '../../containers/DisclosureIndicator'; import { DisclosureImage } from '../../containers/DisclosureIndicator';
import Separator from '../../containers/Separator'; import Separator from '../../containers/Separator';
import I18n from '../../i18n'; import I18n from '../../i18n';
import { MARKDOWN_KEY, CRASH_REPORT_KEY } from '../../lib/rocketchat'; 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 openLink from '../../utils/openLink';
import scrollPersistTaps from '../../utils/scrollPersistTaps'; import scrollPersistTaps from '../../utils/scrollPersistTaps';
import { showErrorAlert } from '../../utils/info'; import { showErrorAlert } from '../../utils/info';
@ -23,6 +26,9 @@ import styles from './styles';
import sharedStyles from '../Styles'; import sharedStyles from '../Styles';
import { loggerConfig, analytics } from '../../utils/log'; import { loggerConfig, analytics } from '../../utils/log';
import { PLAY_MARKET_LINK, APP_STORE_LINK, LICENSE_LINK } from '../../constants/links'; 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 SectionSeparator = React.memo(() => <View style={styles.sectionSeparatorBorder} />);
const ItemInfo = React.memo(({ info }) => ( const ItemInfo = React.memo(({ info }) => (
@ -35,8 +41,12 @@ ItemInfo.propTypes = {
}; };
class SettingsView extends React.Component { class SettingsView extends React.Component {
static navigationOptions = ({ navigation }) => ({ static navigationOptions = ({ navigation, screenProps }) => ({
headerLeft: <DrawerButton navigation={navigation} />, headerLeft: screenProps.split ? (
<CloseModalButton navigation={navigation} testID='settings-view-close' />
) : (
<DrawerButton navigation={navigation} />
),
title: I18n.t('Settings') title: I18n.t('Settings')
}); });
@ -46,7 +56,17 @@ class SettingsView extends React.Component {
useMarkdown: PropTypes.bool, useMarkdown: PropTypes.bool,
allowCrashReport: PropTypes.bool, allowCrashReport: PropTypes.bool,
toggleMarkdown: PropTypes.func, 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) => { toggleMarkdown = (value) => {
@ -96,6 +116,21 @@ class SettingsView extends React.Component {
renderDisclosure = () => <DisclosureImage /> renderDisclosure = () => <DisclosureImage />
renderLogout = () => (
<>
<Separator />
<ListItem
title={I18n.t('Logout')}
testID='settings-logout'
onPress={this.logout}
right={this.renderDisclosure}
color={COLOR_DANGER}
/>
<Separator />
<ItemInfo />
</>
);
renderMarkdownSwitch = () => { renderMarkdownSwitch = () => {
const { useMarkdown } = this.props; const { useMarkdown } = this.props;
return ( return (
@ -119,7 +154,7 @@ class SettingsView extends React.Component {
} }
render() { render() {
const { server } = this.props; const { server, split } = this.props;
return ( return (
<SafeAreaView style={sharedStyles.listSafeArea} testID='settings-view'> <SafeAreaView style={sharedStyles.listSafeArea} testID='settings-view'>
<StatusBar /> <StatusBar />
@ -129,6 +164,21 @@ class SettingsView extends React.Component {
showsVerticalScrollIndicator={false} showsVerticalScrollIndicator={false}
testID='settings-view-list' 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 <ListItem
title={I18n.t('Contact_us')} title={I18n.t('Contact_us')}
onPress={this.sendEmail} onPress={this.sendEmail}
@ -198,6 +248,8 @@ class SettingsView extends React.Component {
<ItemInfo <ItemInfo
info={I18n.t('Crash_report_disclaimer')} info={I18n.t('Crash_report_disclaimer')}
/> />
{ split ? this.renderLogout() : null }
</ScrollView> </ScrollView>
</SafeAreaView> </SafeAreaView>
); );
@ -211,8 +263,9 @@ const mapStateToProps = state => ({
}); });
const mapDispatchToProps = dispatch => ({ const mapDispatchToProps = dispatch => ({
logout: () => dispatch(logoutAction()),
toggleMarkdown: params => dispatch(toggleMarkdownAction(params)), toggleMarkdown: params => dispatch(toggleMarkdownAction(params)),
toggleCrashReport: params => dispatch(toggleCrashReportAction(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 { COLOR_TEXT } from '../../constants/colors';
import database from '../../lib/database'; import database from '../../lib/database';
import { animateNextTransition } from '../../utils/layoutAnimation'; import { animateNextTransition } from '../../utils/layoutAnimation';
import { withSplit } from '../../split';
const keyExtractor = item => item.id; const keyExtractor = item => item.id;
@ -41,7 +42,8 @@ class Sidebar extends Component {
user: PropTypes.object, user: PropTypes.object,
logout: PropTypes.func.isRequired, logout: PropTypes.func.isRequired,
activeItemKey: PropTypes.string, activeItemKey: PropTypes.string,
loadingServer: PropTypes.bool loadingServer: PropTypes.bool,
split: PropTypes.bool
} }
constructor(props) { constructor(props) {
@ -71,7 +73,7 @@ class Sidebar extends Component {
shouldComponentUpdate(nextProps, nextState) { shouldComponentUpdate(nextProps, nextState) {
const { status, showStatus, isAdmin } = this.state; const { status, showStatus, isAdmin } = this.state;
const { const {
Site_Name, user, baseUrl, activeItemKey Site_Name, user, baseUrl, activeItemKey, split
} = this.props; } = this.props;
if (nextState.showStatus !== showStatus) { if (nextState.showStatus !== showStatus) {
return true; return true;
@ -99,6 +101,9 @@ class Sidebar extends Component {
return true; return true;
} }
} }
if (nextProps.split !== split) {
return true;
}
if (!equal(nextState.status, status)) { if (!equal(nextState.status, status)) {
return true; return true;
} }
@ -242,7 +247,9 @@ class Sidebar extends Component {
render() { render() {
const { showStatus } = this.state; const { showStatus } = this.state;
const { user, Site_Name, baseUrl } = this.props; const {
user, Site_Name, baseUrl, split
} = this.props;
if (!user) { if (!user) {
return null; return null;
@ -275,9 +282,9 @@ class Sidebar extends Component {
<CustomIcon name='arrow-down' size={20} style={[styles.headerIcon, showStatus && styles.inverted]} /> <CustomIcon name='arrow-down' size={20} style={[styles.headerIcon, showStatus && styles.inverted]} />
</RectButton> </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} {showStatus ? this.renderStatus() : null}
</ScrollView> </ScrollView>
</SafeAreaView> </SafeAreaView>
@ -303,4 +310,4 @@ const mapDispatchToProps = dispatch => ({
logout: () => dispatch(logoutAction()) 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 { import {
COLOR_DANGER, COLOR_BUTTON_PRIMARY, COLOR_SEPARATOR, COLOR_TEXT, COLOR_TEXT_DESCRIPTION, COLOR_TITLE, COLOR_BACKGROUND_CONTAINER, COLOR_WHITE, COLOR_PRIMARY, HEADER_BACK 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'; } from '../constants/colors';
import { MAX_SCREEN_CONTENT_WIDTH, MAX_CONTENT_WIDTH } from '../constants/tablet';
export default StyleSheet.create({ export default StyleSheet.create({
root: { root: {
@ -16,6 +17,26 @@ export default StyleSheet.create({
padding: 15, padding: 15,
paddingBottom: 30 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: { buttonContainerLastChild: {
marginBottom: 40 marginBottom: 40
}, },
@ -117,6 +138,10 @@ export default StyleSheet.create({
borderTopWidth: StyleSheet.hairlineWidth, borderTopWidth: StyleSheet.hairlineWidth,
borderBottomWidth: StyleSheet.hairlineWidth borderBottomWidth: StyleSheet.hairlineWidth
}, },
separatorLeft: {
borderColor: COLOR_SEPARATOR,
borderLeftWidth: StyleSheet.hairlineWidth
},
textRegular: { textRegular: {
backgroundColor: 'transparent', backgroundColor: 'transparent',
...Platform.select({ ...Platform.select({

View File

@ -21,6 +21,7 @@ import buildMessage from '../../lib/methods/helpers/buildMessage';
import log from '../../utils/log'; import log from '../../utils/log';
import debounce from '../../utils/debounce'; import debounce from '../../utils/debounce';
import protectedFunction from '../../lib/methods/helpers/protectedFunction'; import protectedFunction from '../../lib/methods/helpers/protectedFunction';
import ModalNavigation from '../../lib/ModalNavigation';
const Separator = React.memo(() => <View style={styles.separator} />); const Separator = React.memo(() => <View style={styles.separator} />);
const API_FETCH_COUNT = 50; const API_FETCH_COUNT = 50;
@ -35,7 +36,8 @@ class ThreadMessagesView extends React.Component {
navigation: PropTypes.object, navigation: PropTypes.object,
baseUrl: PropTypes.string, baseUrl: PropTypes.string,
useRealName: PropTypes.bool, useRealName: PropTypes.bool,
customEmojis: PropTypes.object customEmojis: PropTypes.object,
screenProps: PropTypes.object
} }
constructor(props) { constructor(props) {
@ -258,11 +260,16 @@ class ThreadMessagesView extends React.Component {
) )
navToRoomInfo = (navParam) => { navToRoomInfo = (navParam) => {
const { navigation, user } = this.props; const { navigation, user, screenProps } = this.props;
if (navParam.rid === user.id) { if (navParam.rid === user.id) {
return; 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 }) => { 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/UserDefaults (6.3.0):
- GoogleUtilities/Logger - GoogleUtilities/Logger
- JitsiMeetSDK (2.4.0) - JitsiMeetSDK (2.4.0)
- KeyCommands (2.0.3):
- React
- libwebp (1.0.3): - libwebp (1.0.3):
- libwebp/demux (= 1.0.3) - libwebp/demux (= 1.0.3)
- libwebp/mux (= 1.0.3) - libwebp/mux (= 1.0.3)
@ -418,6 +420,7 @@ DEPENDENCIES:
- Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`) - Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`)
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
- JitsiMeetSDK (from `https://github.com/RocketChat/jitsi-meet-ios-sdk-releases.git`) - 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`) - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`) - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
- React (from `../node_modules/react-native/`) - React (from `../node_modules/react-native/`)
@ -536,6 +539,8 @@ EXTERNAL SOURCES:
:podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec"
JitsiMeetSDK: JitsiMeetSDK:
:git: https://github.com/RocketChat/jitsi-meet-ios-sdk-releases.git :git: https://github.com/RocketChat/jitsi-meet-ios-sdk-releases.git
KeyCommands:
:path: "../node_modules/react-native-keycommands"
RCTRequired: RCTRequired:
:path: "../node_modules/react-native/Libraries/RCTRequired" :path: "../node_modules/react-native/Libraries/RCTRequired"
RCTTypeSafety: RCTTypeSafety:
@ -694,6 +699,7 @@ SPEC CHECKSUMS:
GoogleDataTransportCCTSupport: 7455d07b98851aa63e4c05a34dad356ca588479e GoogleDataTransportCCTSupport: 7455d07b98851aa63e4c05a34dad356ca588479e
GoogleUtilities: 9c2c544202301110b29f7974a82e77fdcf12bf51 GoogleUtilities: 9c2c544202301110b29f7974a82e77fdcf12bf51
JitsiMeetSDK: d4a3aeed1a75fd57e6a78e5d202b6051dfcb9320 JitsiMeetSDK: d4a3aeed1a75fd57e6a78e5d202b6051dfcb9320
KeyCommands: f66c535f698ed14b3d3a4e58859d79a827ea907e
libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e
nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48 nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48
QBImagePickerController: d54cf93db6decf26baf6ed3472f336ef35cae022 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/UserDefaults (6.3.0):
- GoogleUtilities/Logger - GoogleUtilities/Logger
- JitsiMeetSDK (2.4.0) - JitsiMeetSDK (2.4.0)
- KeyCommands (2.0.3):
- React
- libwebp (1.0.3): - libwebp (1.0.3):
- libwebp/demux (= 1.0.3) - libwebp/demux (= 1.0.3)
- libwebp/mux (= 1.0.3) - libwebp/mux (= 1.0.3)
@ -418,6 +420,7 @@ DEPENDENCIES:
- Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`) - Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`)
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
- JitsiMeetSDK (from `https://github.com/RocketChat/jitsi-meet-ios-sdk-releases.git`) - 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`) - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`) - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
- React (from `../node_modules/react-native/`) - React (from `../node_modules/react-native/`)
@ -536,6 +539,8 @@ EXTERNAL SOURCES:
:podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec"
JitsiMeetSDK: JitsiMeetSDK:
:git: https://github.com/RocketChat/jitsi-meet-ios-sdk-releases.git :git: https://github.com/RocketChat/jitsi-meet-ios-sdk-releases.git
KeyCommands:
:path: "../node_modules/react-native-keycommands"
RCTRequired: RCTRequired:
:path: "../node_modules/react-native/Libraries/RCTRequired" :path: "../node_modules/react-native/Libraries/RCTRequired"
RCTTypeSafety: RCTTypeSafety:
@ -694,6 +699,7 @@ SPEC CHECKSUMS:
GoogleDataTransportCCTSupport: 7455d07b98851aa63e4c05a34dad356ca588479e GoogleDataTransportCCTSupport: 7455d07b98851aa63e4c05a34dad356ca588479e
GoogleUtilities: 9c2c544202301110b29f7974a82e77fdcf12bf51 GoogleUtilities: 9c2c544202301110b29f7974a82e77fdcf12bf51
JitsiMeetSDK: d4a3aeed1a75fd57e6a78e5d202b6051dfcb9320 JitsiMeetSDK: d4a3aeed1a75fd57e6a78e5d202b6051dfcb9320
KeyCommands: f66c535f698ed14b3d3a4e58859d79a827ea907e
libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e
nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48 nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48
QBImagePickerController: d54cf93db6decf26baf6ed3472f336ef35cae022 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" 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 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' 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" 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"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" 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_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 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" 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 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' 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" 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"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" 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_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 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" 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 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' 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" 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"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" 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_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 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" 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 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' 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" 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"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" 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_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/. PODS_PODFILE_DIR_PATH = ${SRCROOT}/.

View File

@ -23,6 +23,7 @@
1E1EA81A2326CD5100E22452 /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E1EA8192326CD5100E22452 /* libsqlite3.tbd */; }; 1E1EA81A2326CD5100E22452 /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E1EA8192326CD5100E22452 /* libsqlite3.tbd */; };
1E25743422CBA2CF005A877F /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7ACD4853222860DE00442C55 /* JavaScriptCore.framework */; }; 1E25743422CBA2CF005A877F /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7ACD4853222860DE00442C55 /* JavaScriptCore.framework */; };
1E55FDB32320675C0048D2F9 /* libWatermelonDB.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7AAA749B23043AD300F1ADE9 /* libWatermelonDB.a */; }; 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 */; }; 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, ); }; }; 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 */; }; 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; }; 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; }; 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; }; 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; }; 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>"; }; 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>"; }; 1EC6ACB822CB9FC300A41C61 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@ -153,6 +155,7 @@
children = ( children = (
7A006F13229C83B600803143 /* GoogleService-Info.plist */, 7A006F13229C83B600803143 /* GoogleService-Info.plist */,
60B2A6A31FC4588700BD58E5 /* RocketChatRN.entitlements */, 60B2A6A31FC4588700BD58E5 /* RocketChatRN.entitlements */,
1E7B75562350CF480050D8CB /* LaunchScreen.storyboard */,
008F07F21AC5B25A0029DE68 /* main.jsbundle */, 008F07F21AC5B25A0029DE68 /* main.jsbundle */,
13B07FAF1A68108700A75B9A /* AppDelegate.h */, 13B07FAF1A68108700A75B9A /* AppDelegate.h */,
13B07FB01A68108700A75B9A /* AppDelegate.m */, 13B07FB01A68108700A75B9A /* AppDelegate.m */,
@ -398,6 +401,7 @@
files = ( files = (
7A55F1C52236D541005109A0 /* custom.ttf in Resources */, 7A55F1C52236D541005109A0 /* custom.ttf in Resources */,
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
1E7B75582350CF480050D8CB /* LaunchScreen.storyboard in Resources */,
7A006F14229C83B600803143 /* GoogleService-Info.plist in Resources */, 7A006F14229C83B600803143 /* GoogleService-Info.plist in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -679,7 +683,7 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
APPLICATION_EXTENSION_API_ONLY = NO; APPLICATION_EXTENSION_API_ONLY = NO;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = "";
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = RocketChatRN/RocketChatRN.entitlements; CODE_SIGN_ENTITLEMENTS = RocketChatRN/RocketChatRN.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_IDENTITY = "iPhone Developer";
@ -699,6 +703,7 @@
"$(SRCROOT)/../node_modules/@nozbe/watermelondb/native/ios/WatermelonDB/SupportingFiles/**", "$(SRCROOT)/../node_modules/@nozbe/watermelondb/native/ios/WatermelonDB/SupportingFiles/**",
); );
INFOPLIST_FILE = RocketChatRN/Info.plist; INFOPLIST_FILE = RocketChatRN/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = ( LIBRARY_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
@ -716,6 +721,7 @@
SWIFT_OBJC_BRIDGING_HEADER = "RocketChatRN-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "RocketChatRN-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";
}; };
name = Debug; name = Debug;
@ -727,7 +733,7 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
APPLICATION_EXTENSION_API_ONLY = NO; APPLICATION_EXTENSION_API_ONLY = NO;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = "";
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = RocketChatRN/RocketChatRN.entitlements; CODE_SIGN_ENTITLEMENTS = RocketChatRN/RocketChatRN.entitlements;
CODE_SIGN_IDENTITY = "iPhone Distribution"; CODE_SIGN_IDENTITY = "iPhone Distribution";
@ -747,6 +753,7 @@
"$(SRCROOT)/../node_modules/@nozbe/watermelondb/native/ios/WatermelonDB/SupportingFiles/**", "$(SRCROOT)/../node_modules/@nozbe/watermelondb/native/ios/WatermelonDB/SupportingFiles/**",
); );
INFOPLIST_FILE = RocketChatRN/Info.plist; INFOPLIST_FILE = RocketChatRN/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = ( LIBRARY_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
@ -763,6 +770,7 @@
PROVISIONING_PROFILE_SPECIFIER = "match AppStore chat.rocket.reactnative"; PROVISIONING_PROFILE_SPECIFIER = "match AppStore chat.rocket.reactnative";
SWIFT_OBJC_BRIDGING_HEADER = "RocketChatRN-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "RocketChatRN-Bridging-Header.h";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";
}; };
name = Release; name = Release;
@ -809,7 +817,7 @@
"$(inherited)", "$(inherited)",
"$(SRCROOT)/../node_modules/rn-extensions-share/ios/**", "$(SRCROOT)/../node_modules/rn-extensions-share/ios/**",
"$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**", "$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**",
"$PODS_CONFIGURATION_BUILD_DIR/Firebase", $PODS_CONFIGURATION_BUILD_DIR/Firebase,
); );
INFOPLIST_FILE = ShareRocketChatRN/Info.plist; INFOPLIST_FILE = ShareRocketChatRN/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0; IPHONEOS_DEPLOYMENT_TARGET = 9.0;
@ -876,7 +884,7 @@
PROVISIONING_PROFILE_SPECIFIER = "Development chat.rocket.reactnative.ShareExtension"; PROVISIONING_PROFILE_SPECIFIER = "Development chat.rocket.reactnative.ShareExtension";
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1; TARGETED_DEVICE_FAMILY = "1,2";
}; };
name = Debug; name = Debug;
}; };
@ -922,7 +930,7 @@
"$(inherited)", "$(inherited)",
"$(SRCROOT)/../node_modules/rn-extensions-share/ios/**", "$(SRCROOT)/../node_modules/rn-extensions-share/ios/**",
"$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**", "$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**",
"$PODS_CONFIGURATION_BUILD_DIR/Firebase", $PODS_CONFIGURATION_BUILD_DIR/Firebase,
); );
INFOPLIST_FILE = ShareRocketChatRN/Info.plist; INFOPLIST_FILE = ShareRocketChatRN/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0; IPHONEOS_DEPLOYMENT_TARGET = 9.0;
@ -988,7 +996,7 @@
PROVISIONING_PROFILE_SPECIFIER = "chat.rocket.reactnative.ShareExtension AppStore"; PROVISIONING_PROFILE_SPECIFIER = "chat.rocket.reactnative.ShareExtension AppStore";
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1; TARGETED_DEVICE_FAMILY = "1,2";
}; };
name = Release; 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> <array>
<string>custom.ttf</string> <string>custom.ttf</string>
</array> </array>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
</dict>
<key>UIBackgroundModes</key> <key>UIBackgroundModes</key>
<array> <array>
<string>voip</string> <string>voip</string>
</array> </array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key> <key>UIRequiredDeviceCapabilities</key>
<array> <array>
<string>armv7</string> <string>armv7</string>
@ -91,6 +98,7 @@
<string>UIInterfaceOrientationPortrait</string> <string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string> <string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string> <string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array> </array>
<key>UIViewControllerBasedStatusBarAppearance</key> <key>UIViewControllerBasedStatusBarAppearance</key>
<false/> <false/>

View File

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

View File

@ -141,6 +141,153 @@ index a134d2e..a88c099 100644
[self _sendFrameWithOpcode:RCTSROpCodeConnectionClose data:payload]; [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 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 index ef2ae93..2795802 100644
--- a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoModule.java --- 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