[FIX] Share extension memory issues on iOS (#2845)

* Remove unnecessary class prop

* Stop rendering servers when there's only one

* Map and alloc only necessary columns from query

* Fetch servers count instead of all servers records

* Fetch only needed servers

* Separators

* Remove renderContent

* Minor fix

* Refactor query

* Smaller avatars in memory

* Fix getItemLayout

* Add topic

* Load less pods

* tests

* Import only used functions from lodash

* Fix pods

* Import only used functions from semver

* Fix media sharing

* Update pods

* Disables preview and thumb on iOS

* Update expo-video-thumbnail

* Unnecessary change
This commit is contained in:
Diego Mello 2021-02-01 14:18:55 -03:00 committed by GitHub
parent cf59644a56
commit acd5f04314
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 1569 additions and 4729 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { View } from 'react-native'; import { View } from 'react-native';
import _ from 'lodash'; import range from 'lodash/range';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import styles from './styles'; import styles from './styles';
@ -11,7 +11,7 @@ const SIZE_FULL = 16;
const Dots = React.memo(({ passcode, theme, length }) => ( const Dots = React.memo(({ passcode, theme, length }) => (
<View style={styles.dotsContainer}> <View style={styles.dotsContainer}>
{_.range(length).map((val) => { {range(length).map((val) => {
const lengthSup = (passcode.length >= val + 1); const lengthSup = (passcode.length >= val + 1);
const height = lengthSup ? SIZE_FULL : SIZE_EMPTY; const height = lengthSup ? SIZE_FULL : SIZE_EMPTY;
const width = lengthSup ? SIZE_FULL : SIZE_EMPTY; const width = lengthSup ? SIZE_FULL : SIZE_EMPTY;

View File

@ -2,7 +2,7 @@ import React, {
useState, forwardRef, useImperativeHandle, useRef useState, forwardRef, useImperativeHandle, useRef
} from 'react'; } from 'react';
import { Col, Row, Grid } from 'react-native-easy-grid'; import { Col, Row, Grid } from 'react-native-easy-grid';
import _ from 'lodash'; import range from 'lodash/range';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import * as Animatable from 'react-native-animatable'; import * as Animatable from 'react-native-animatable';
import * as Haptics from 'expo-haptics'; import * as Haptics from 'expo-haptics';
@ -84,21 +84,21 @@ const Base = forwardRef(({
</Animatable.View> </Animatable.View>
</Row> </Row>
<Row style={[styles.row, styles.buttonRow]}> <Row style={[styles.row, styles.buttonRow]}>
{_.range(1, 4).map(i => ( {range(1, 4).map(i => (
<Col key={i} style={styles.colButton}> <Col key={i} style={styles.colButton}>
<Button text={i} theme={theme} onPress={onPressNumber} /> <Button text={i} theme={theme} onPress={onPressNumber} />
</Col> </Col>
))} ))}
</Row> </Row>
<Row style={[styles.row, styles.buttonRow]}> <Row style={[styles.row, styles.buttonRow]}>
{_.range(4, 7).map(i => ( {range(4, 7).map(i => (
<Col key={i} style={styles.colButton}> <Col key={i} style={styles.colButton}>
<Button text={i} theme={theme} onPress={onPressNumber} /> <Button text={i} theme={theme} onPress={onPressNumber} />
</Col> </Col>
))} ))}
</Row> </Row>
<Row style={[styles.row, styles.buttonRow]}> <Row style={[styles.row, styles.buttonRow]}>
{_.range(7, 10).map(i => ( {range(7, 10).map(i => (
<Col key={i} style={styles.colButton}> <Col key={i} style={styles.colButton}>
<Button text={i} theme={theme} onPress={onPressNumber} /> <Button text={i} theme={theme} onPress={onPressNumber} />
</Col> </Col>

View File

@ -1,6 +1,6 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { View, Text, InteractionManager } from 'react-native'; import { View, Text, InteractionManager } from 'react-native';
import _ from 'lodash'; import isEmpty from 'lodash/isEmpty';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { sha256 } from 'js-sha256'; import { sha256 } from 'js-sha256';
import Modal from 'react-native-modal'; import Modal from 'react-native-modal';
@ -47,7 +47,7 @@ const TwoFactor = React.memo(({ theme, isMasterDetail }) => {
const sendEmail = () => RocketChat.sendEmailCode(); const sendEmail = () => RocketChat.sendEmailCode();
useDeepCompareEffect(() => { useDeepCompareEffect(() => {
if (!_.isEmpty(data)) { if (!isEmpty(data)) {
setCode(''); setCode('');
setVisible(true); setVisible(true);
} else { } else {

View File

@ -1,4 +1,5 @@
import semver from 'semver'; import gte from 'semver/functions/gte';
import coerce from 'semver/functions/coerce';
import reduxStore from '../createStore'; import reduxStore from '../createStore';
import database from '../database'; import database from '../database';
@ -33,7 +34,7 @@ export function getEnterpriseModules() {
return new Promise(async(resolve) => { return new Promise(async(resolve) => {
try { try {
const { version: serverVersion, server: serverId } = reduxStore.getState().server; const { version: serverVersion, server: serverId } = reduxStore.getState().server;
if (serverVersion && semver.gte(semver.coerce(serverVersion), '3.1.0')) { if (serverVersion && gte(coerce(serverVersion), '3.1.0')) {
// RC 3.1.0 // RC 3.1.0
const enterpriseModules = await this.methodCallWrapper('license:getModules'); const enterpriseModules = await this.methodCallWrapper('license:getModules');
if (enterpriseModules) { if (enterpriseModules) {

View File

@ -1,5 +1,5 @@
import { InteractionManager } from 'react-native'; import { InteractionManager } from 'react-native';
import semver from 'semver'; import lt from 'semver/functions/lt';
import orderBy from 'lodash/orderBy'; import orderBy from 'lodash/orderBy';
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord'; import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
@ -91,7 +91,7 @@ export function getCustomEmojis() {
const updatedSince = await getUpdatedSince(allRecords); const updatedSince = await getUpdatedSince(allRecords);
// if server version is lower than 0.75.0, fetches from old api // if server version is lower than 0.75.0, fetches from old api
if (serverVersion && semver.lt(serverVersion, '0.75.0')) { if (serverVersion && lt(serverVersion, '0.75.0')) {
// RC 0.61.0 // RC 0.61.0
const result = await this.sdk.get('emoji-custom'); const result = await this.sdk.get('emoji-custom');

View File

@ -1,7 +1,7 @@
import { InteractionManager } from 'react-native'; import { InteractionManager } from 'react-native';
import semver from 'semver'; import lt from 'semver/functions/lt';
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord'; import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
import { orderBy } from 'lodash'; import orderBy from 'lodash/orderBy';
import database from '../database'; import database from '../database';
import log from '../../utils/log'; import log from '../../utils/log';
@ -79,7 +79,7 @@ export default function() {
const allRecords = await permissionsCollection.query().fetch(); const allRecords = await permissionsCollection.query().fetch();
// if server version is lower than 0.73.0, fetches from old api // if server version is lower than 0.73.0, fetches from old api
if (serverVersion && semver.lt(serverVersion, '0.73.0')) { if (serverVersion && lt(serverVersion, '0.73.0')) {
// RC 0.66.0 // RC 0.66.0
const result = await this.sdk.get('permissions.list'); const result = await this.sdk.get('permissions.list');
if (!result.success) { if (!result.success) {

View File

@ -1,5 +1,6 @@
import { InteractionManager } from 'react-native'; import { InteractionManager } from 'react-native';
import semver from 'semver'; import lt from 'semver/functions/lt';
import gte from 'semver/functions/gte';
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord'; import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
import reduxStore from '../createStore'; import reduxStore from '../createStore';
@ -11,7 +12,7 @@ export function subscribeUsersPresence() {
const serverVersion = reduxStore.getState().server.version; const serverVersion = reduxStore.getState().server.version;
// if server is lower than 1.1.0 // if server is lower than 1.1.0
if (serverVersion && semver.lt(serverVersion, '1.1.0')) { if (serverVersion && lt(serverVersion, '1.1.0')) {
if (this.activeUsersSubTimeout) { if (this.activeUsersSubTimeout) {
clearTimeout(this.activeUsersSubTimeout); clearTimeout(this.activeUsersSubTimeout);
this.activeUsersSubTimeout = false; this.activeUsersSubTimeout = false;
@ -36,11 +37,11 @@ export default async function getUsersPresence() {
const { user: loggedUser } = reduxStore.getState().login; const { user: loggedUser } = reduxStore.getState().login;
// if server is greather than or equal 1.1.0 // if server is greather than or equal 1.1.0
if (serverVersion && semver.gte(serverVersion, '1.1.0')) { if (serverVersion && gte(serverVersion, '1.1.0')) {
let params = {}; let params = {};
// if server is greather than or equal 3.0.0 // if server is greather than or equal 3.0.0
if (serverVersion && semver.gte(serverVersion, '3.0.0')) { if (serverVersion && gte(serverVersion, '3.0.0')) {
// if not have any id // if not have any id
if (!ids.length) { if (!ids.length) {
return; return;

View File

@ -1,5 +1,7 @@
import { InteractionManager } from 'react-native'; import { InteractionManager } from 'react-native';
import semver from 'semver'; import lt from 'semver/functions/lt';
import gte from 'semver/functions/gte';
import coerce from 'semver/functions/coerce';
import { import {
Rocketchat as RocketchatClient, Rocketchat as RocketchatClient,
settings as RocketChatSettings settings as RocketChatSettings
@ -132,7 +134,7 @@ const RocketChat = {
message: I18n.t('Not_RC_Server', { contact: I18n.t('Contact_your_server_admin') }) message: I18n.t('Not_RC_Server', { contact: I18n.t('Contact_your_server_admin') })
}; };
} }
if (semver.lt(jsonRes.version, MIN_ROCKETCHAT_VERSION)) { if (lt(jsonRes.version, MIN_ROCKETCHAT_VERSION)) {
return { return {
success: false, success: false,
message: I18n.t('Invalid_server_version', { message: I18n.t('Invalid_server_version', {
@ -465,7 +467,7 @@ const RocketChat = {
// Force normalized params for 2FA starting RC 3.9.0. // Force normalized params for 2FA starting RC 3.9.0.
const serverVersion = reduxStore.getState().server.version; const serverVersion = reduxStore.getState().server.version;
if (serverVersion && semver.gte(semver.coerce(serverVersion), '3.9.0')) { if (serverVersion && gte(coerce(serverVersion), '3.9.0')) {
const user = params.user ?? params.username; const user = params.user ?? params.username;
const password = params.password ?? params.ldapPass ?? params.crowdPassword; const password = params.password ?? params.ldapPass ?? params.crowdPassword;
params = { user, password }; params = { user, password };
@ -1372,7 +1374,7 @@ const RocketChat = {
}, },
readThreads(tmid) { readThreads(tmid) {
const serverVersion = reduxStore.getState().server.version; const serverVersion = reduxStore.getState().server.version;
if (serverVersion && semver.gte(semver.coerce(serverVersion), '3.4.0')) { if (serverVersion && gte(coerce(serverVersion), '3.4.0')) {
// RC 3.4.0 // RC 3.4.0
return this.methodCallWrapper('readThreads', tmid); return this.methodCallWrapper('readThreads', tmid);
} }

View File

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import _ from 'lodash'; import isEqual from 'lodash/isEqual';
import I18n from '../../i18n'; import I18n from '../../i18n';
import styles from './styles'; import styles from './styles';
@ -45,7 +45,7 @@ const formatMsg = ({
return `${ prefix }${ lastMessage.msg }`; return `${ prefix }${ lastMessage.msg }`;
}; };
const arePropsEqual = (oldProps, newProps) => _.isEqual(oldProps, newProps); const arePropsEqual = (oldProps, newProps) => isEqual(oldProps, newProps);
const LastMessage = React.memo(({ const LastMessage = React.memo(({
lastMessage, type, showLastMessage, username, alert, useRealName, theme lastMessage, type, showLastMessage, username, alert, useRealName, theme

View File

@ -2,7 +2,8 @@ import { put, takeLatest } from 'redux-saga/effects';
import { Alert } from 'react-native'; import { Alert } from 'react-native';
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord'; import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
import { Q } from '@nozbe/watermelondb'; import { Q } from '@nozbe/watermelondb';
import semver from 'semver'; import valid from 'semver/functions/valid';
import coerce from 'semver/functions/coerce';
import Navigation from '../lib/Navigation'; import Navigation from '../lib/Navigation';
import { SERVER } from '../actions/actionsTypes'; import { SERVER } from '../actions/actionsTypes';
@ -39,9 +40,9 @@ const getServerInfo = function* getServerInfo({ server, raiseError = true }) {
return; return;
} }
let serverVersion = semver.valid(serverInfo.version); let serverVersion = valid(serverInfo.version);
if (!serverVersion) { if (!serverVersion) {
({ version: serverVersion } = semver.coerce(serverInfo.version)); ({ version: serverVersion } = coerce(serverInfo.version));
} }
const serversDB = database.servers; const serversDB = database.servers;

View File

@ -1,5 +1,5 @@
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import { isEmpty } from 'lodash'; import isEmpty from 'lodash/isEmpty';
const getUser = (state) => { const getUser = (state) => {
if (!isEmpty(state.share?.user)) { if (!isEmpty(state.share?.user)) {

View File

@ -1,4 +1,5 @@
import semver from 'semver'; import lt from 'semver/functions/lt';
import coerce from 'semver/functions/coerce';
const formatUrl = (url, size, query) => `${ url }?format=png&size=${ size }${ query }`; const formatUrl = (url, size, query) => `${ url }?format=png&size=${ size }${ query }`;
@ -8,14 +9,12 @@ export const avatarURL = ({
let room; let room;
if (type === 'd') { if (type === 'd') {
room = text; room = text;
} else if (rid && !(serverVersion && semver.lt(semver.coerce(serverVersion), '3.6.0'))) { } else if (rid && !(serverVersion && lt(coerce(serverVersion), '3.6.0'))) {
room = `room/${ rid }`; room = `room/${ rid }`;
} else { } else {
room = `@${ text }`; room = `@${ text }`;
} }
const uriSize = size > 100 ? size : 100;
const { id, token } = user; const { id, token } = user;
let query = ''; let query = '';
if (id && token && blockUnauthenticatedAccess) { if (id && token && blockUnauthenticatedAccess) {
@ -30,8 +29,8 @@ export const avatarURL = ({
return avatar; return avatar;
} }
return formatUrl(`${ server }${ avatar }`, uriSize, query); return formatUrl(`${ server }${ avatar }`, size, query);
} }
return formatUrl(`${ server }/avatar/${ room }`, uriSize, query); return formatUrl(`${ server }/avatar/${ room }`, size, query);
}; };

View File

@ -3,7 +3,7 @@ import { StyleSheet } from 'react-native';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import Orientation from 'react-native-orientation-locker'; import Orientation from 'react-native-orientation-locker';
import useDeepCompareEffect from 'use-deep-compare-effect'; import useDeepCompareEffect from 'use-deep-compare-effect';
import _ from 'lodash'; import isEmpty from 'lodash/isEmpty';
import Modal from 'react-native-modal'; import Modal from 'react-native-modal';
import Touchable from 'react-native-platform-touchable'; import Touchable from 'react-native-platform-touchable';
@ -32,7 +32,7 @@ const ChangePasscodeView = React.memo(({ theme }) => {
const [data, setData] = useState({}); const [data, setData] = useState({});
useDeepCompareEffect(() => { useDeepCompareEffect(() => {
if (!_.isEmpty(data)) { if (!isEmpty(data)) {
setVisible(true); setVisible(true);
} else { } else {
setVisible(false); setVisible(false);

View File

@ -5,7 +5,7 @@ import {
} from 'react-native'; } from 'react-native';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import equal from 'deep-equal'; import equal from 'deep-equal';
import { orderBy } from 'lodash'; import orderBy from 'lodash/orderBy';
import { Q } from '@nozbe/watermelondb'; import { Q } from '@nozbe/watermelondb';
import Touch from '../utils/touch'; import Touch from '../utils/touch';

View File

@ -6,7 +6,8 @@ import prompt from 'react-native-prompt-android';
import SHA256 from 'js-sha256'; 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 { isEqual, omit } from 'lodash'; import isEqual from 'lodash/isEqual';
import omit from 'lodash/omit';
import Touch from '../../utils/touch'; import Touch from '../../utils/touch';
import KeyboardView from '../../presentation/KeyboardView'; import KeyboardView from '../../presentation/KeyboardView';

View File

@ -4,8 +4,9 @@ import {
View, Text, Alert, Share, Switch View, Text, Alert, Share, Switch
} from 'react-native'; } from 'react-native';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import _ from 'lodash'; import isEmpty from 'lodash/isEmpty';
import semver from 'semver'; import lt from 'semver/functions/lt';
import coerce from 'semver/functions/coerce';
import Touch from '../../utils/touch'; import Touch from '../../utils/touch';
import { setLoading as setLoadingAction } from '../../actions/selectedUsers'; import { setLoading as setLoadingAction } from '../../actions/selectedUsers';
@ -113,7 +114,7 @@ class RoomActionsView extends React.Component {
} catch (e) { } catch (e) {
log(e); log(e);
} }
} else if (room.t === 'd' && _.isEmpty(member)) { } else if (room.t === 'd' && isEmpty(member)) {
this.updateRoomMember(); this.updateRoomMember();
} }
@ -251,7 +252,7 @@ class RoomActionsView extends React.Component {
const { encrypted } = room; const { encrypted } = room;
const { serverVersion } = this.props; const { serverVersion } = this.props;
let hasPermission = false; let hasPermission = false;
if (serverVersion && semver.lt(semver.coerce(serverVersion), '3.11.0')) { if (serverVersion && lt(coerce(serverVersion), '3.11.0')) {
hasPermission = canEdit; hasPermission = canEdit;
} else { } else {
hasPermission = canToggleEncryption; hasPermission = canToggleEncryption;

View File

@ -9,7 +9,9 @@ import { BLOCK_CONTEXT } from '@rocket.chat/ui-kit';
import ImagePicker from 'react-native-image-crop-picker'; import ImagePicker from 'react-native-image-crop-picker';
import isEqual from 'lodash/isEqual'; import isEqual from 'lodash/isEqual';
import isEmpty from 'lodash/isEmpty'; import isEmpty from 'lodash/isEmpty';
import semver from 'semver'; import lt from 'semver/functions/lt';
import coerce from 'semver/functions/coerce';
import database from '../../lib/database'; import database from '../../lib/database';
import { deleteRoom as deleteRoomAction } from '../../actions/room'; import { deleteRoom as deleteRoomAction } from '../../actions/room';
@ -407,7 +409,7 @@ class RoomInfoEditView extends React.Component {
isServerVersionLowerThan = (version) => { isServerVersionLowerThan = (version) => {
const { serverVersion } = this.props; const { serverVersion } = this.props;
return serverVersion && semver.lt(semver.coerce(serverVersion), version); return serverVersion && lt(coerce(serverVersion), version);
} }
render() { render() {
@ -547,7 +549,7 @@ class RoomInfoEditView extends React.Component {
] ]
: null : null
} }
{serverVersion && !semver.lt(serverVersion, '3.0.0') ? ( {serverVersion && !lt(serverVersion, '3.0.0') ? (
<SwitchContainer <SwitchContainer
value={enableSysMes} value={enableSysMes}
leftLabelPrimary={I18n.t('Hide_System_Messages')} leftLabelPrimary={I18n.t('Hide_System_Messages')}

View File

@ -4,7 +4,7 @@ import { View, Text, ScrollView } from 'react-native';
import { BorderlessButton } from 'react-native-gesture-handler'; import { BorderlessButton } from 'react-native-gesture-handler';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import UAParser from 'ua-parser-js'; import UAParser from 'ua-parser-js';
import _ from 'lodash'; import isEmpty from 'lodash/isEmpty';
import database from '../../lib/database'; import database from '../../lib/database';
import { CustomIcon } from '../../lib/Icons'; import { CustomIcon } from '../../lib/Icons';
@ -169,7 +169,7 @@ class RoomInfoView extends React.Component {
loadUser = async() => { loadUser = async() => {
const { room, roomUser } = this.state; const { room, roomUser } = this.state;
if (_.isEmpty(roomUser)) { if (isEmpty(roomUser)) {
try { try {
const roomUserId = RocketChat.getUidDirectMessage(room); const roomUserId = RocketChat.getUidDirectMessage(room);
const result = await RocketChat.getUserInfo(roomUserId); const result = await RocketChat.getUserInfo(roomUserId);
@ -224,7 +224,7 @@ class RoomInfoView extends React.Component {
// We don't need to create a direct // We don't need to create a direct
const member = route.params?.member; const member = route.params?.member;
if (!_.isEmpty(member)) { if (!isEmpty(member)) {
return resolve(); return resolve();
} }

View File

@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import Modal from 'react-native-modal'; import Modal from 'react-native-modal';
import useDeepCompareEffect from 'use-deep-compare-effect'; import useDeepCompareEffect from 'use-deep-compare-effect';
import _ from 'lodash'; import isEmpty from 'lodash/isEmpty';
import Orientation from 'react-native-orientation-locker'; import Orientation from 'react-native-orientation-locker';
import { withTheme } from '../theme'; import { withTheme } from '../theme';
@ -16,7 +16,7 @@ const ScreenLockedView = ({ theme }) => {
const [data, setData] = useState({}); const [data, setData] = useState({});
useDeepCompareEffect(() => { useDeepCompareEffect(() => {
if (!_.isEmpty(data)) { if (!isEmpty(data)) {
setVisible(true); setVisible(true);
} else { } else {
setVisible(false); setVisible(false);

View File

@ -1,33 +1,20 @@
import React from 'react'; import React from 'react';
import { import { FlatList } from 'react-native';
FlatList, StyleSheet, View
} from 'react-native';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { Q } from '@nozbe/watermelondb';
import I18n from '../i18n'; import I18n from '../i18n';
import StatusBar from '../containers/StatusBar'; import StatusBar from '../containers/StatusBar';
import { themes } from '../constants/colors';
import ServerItem, { ROW_HEIGHT } from '../presentation/ServerItem'; import ServerItem, { ROW_HEIGHT } from '../presentation/ServerItem';
import sharedStyles from './Styles';
import RocketChat from '../lib/rocketchat'; import RocketChat from '../lib/rocketchat';
import { withTheme } from '../theme'; import database from '../lib/database';
import SafeAreaView from '../containers/SafeAreaView'; import SafeAreaView from '../containers/SafeAreaView';
import * as List from '../containers/List';
const getItemLayout = (data, index) => ({ length: ROW_HEIGHT, offset: ROW_HEIGHT * index, index }); const getItemLayout = (data, index) => ({ length: ROW_HEIGHT, offset: ROW_HEIGHT * index, index });
const keyExtractor = item => item.id; const keyExtractor = item => item.id;
const styles = StyleSheet.create({
list: {
marginVertical: 32,
...sharedStyles.separatorVertical
},
separator: {
...sharedStyles.separatorBottom,
marginLeft: 48
}
});
class SelectServerView extends React.Component { class SelectServerView extends React.Component {
static navigationOptions = () => ({ static navigationOptions = () => ({
title: I18n.t('Select_Server') title: I18n.t('Select_Server')
@ -35,19 +22,16 @@ class SelectServerView extends React.Component {
static propTypes = { static propTypes = {
server: PropTypes.string, server: PropTypes.string,
route: PropTypes.object, navigation: PropTypes.object
navigation: PropTypes.object,
theme: PropTypes.string
} }
constructor(props) { state = { servers: [] };
super(props);
const { route } = this.props; async componentDidMount() {
const servers = route.params?.servers ?? []; const serversDB = database.servers;
const filteredServers = servers.filter(server => server.roomsUpdatedAt); const serversCollection = serversDB.collections.get('servers');
this.state = { const servers = await serversCollection.query(Q.where('rooms_updated_at', Q.notEq(null))).fetch();
servers: filteredServers this.setState({ servers });
};
} }
select = async(server) => { select = async(server) => {
@ -62,43 +46,34 @@ class SelectServerView extends React.Component {
} }
renderItem = ({ item }) => { renderItem = ({ item }) => {
const { server, theme } = this.props; const { server } = this.props;
return ( return (
<ServerItem <ServerItem
onPress={() => this.select(item.id)} onPress={() => this.select(item.id)}
item={item} item={item}
hasCheck={item.id === server} hasCheck={item.id === server}
theme={theme}
/> />
); );
} }
renderSeparator = () => {
const { theme } = this.props;
return <View style={[styles.separator, { borderColor: themes[theme].separatorColor }]} />;
}
render() { render() {
const { servers } = this.state; const { servers } = this.state;
const { theme } = this.props;
return ( return (
<SafeAreaView> <SafeAreaView>
<StatusBar /> <StatusBar />
<View style={[styles.list, { borderColor: themes[theme].separatorColor }]}> <FlatList
<FlatList data={servers}
data={servers} keyExtractor={keyExtractor}
keyExtractor={keyExtractor} renderItem={this.renderItem}
renderItem={this.renderItem} getItemLayout={getItemLayout} // Refactor row_height
getItemLayout={getItemLayout} contentContainerStyle={List.styles.contentContainerStyleFlatList}
contentContainerStyle={{ backgroundColor: themes[theme].backgroundColor }} ItemSeparatorComponent={List.Separator}
ItemSeparatorComponent={this.renderSeparator} ListHeaderComponent={List.Separator}
enableEmptySections ListFooterComponent={List.Separator}
removeClippedSubviews enableEmptySections
keyboardShouldPersistTaps='always' removeClippedSubviews
windowSize={7} keyboardShouldPersistTaps='always'
bounces={false} />
/>
</View>
</SafeAreaView> </SafeAreaView>
); );
} }
@ -108,4 +83,4 @@ const mapStateToProps = (({ share }) => ({
server: share.server.server server: share.server.server
})); }));
export default connect(mapStateToProps)(withTheme(SelectServerView)); export default connect(mapStateToProps)(SelectServerView);

View File

@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import { View, StyleSheet, FlatList } from 'react-native'; import { View, StyleSheet, FlatList } from 'react-native';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import equal from 'deep-equal'; import equal from 'deep-equal';
import { orderBy } from 'lodash'; import orderBy from 'lodash/orderBy';
import { Q } from '@nozbe/watermelondb'; import { Q } from '@nozbe/watermelondb';
import database from '../lib/database'; import database from '../lib/database';

View File

@ -18,9 +18,8 @@ import ServerItem from '../../presentation/ServerItem';
import * as HeaderButton from '../../containers/HeaderButton'; import * as HeaderButton from '../../containers/HeaderButton';
import ShareListHeader from './Header'; import ShareListHeader from './Header';
import ActivityIndicator from '../../containers/ActivityIndicator'; import ActivityIndicator from '../../containers/ActivityIndicator';
import * as List from '../../containers/List';
import styles from './styles'; import styles from './styles';
import StatusBar from '../../containers/StatusBar';
import { themes } from '../../constants/colors'; import { themes } from '../../constants/colors';
import { animateNextTransition } from '../../utils/layoutAnimation'; import { animateNextTransition } from '../../utils/layoutAnimation';
import { withTheme } from '../../theme'; import { withTheme } from '../../theme';
@ -33,7 +32,7 @@ const permission = {
message: I18n.t('Read_External_Permission_Message') message: I18n.t('Read_External_Permission_Message')
}; };
const getItemLayout = (data, index) => ({ length: ROW_HEIGHT, offset: ROW_HEIGHT * index, index }); const getItemLayout = (data, index) => ({ length: data.length, offset: ROW_HEIGHT * index, index });
const keyExtractor = item => item.rid; const keyExtractor = item => item.rid;
class ShareListView extends React.Component { class ShareListView extends React.Component {
@ -47,13 +46,12 @@ class ShareListView extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.chats = [];
this.state = { this.state = {
searching: false, searching: false,
searchText: '', searchText: '',
searchResults: [], searchResults: [],
chats: [], chats: [],
servers: [], serversCount: 0,
attachments: [], attachments: [],
text: '', text: '',
loading: true, loading: true,
@ -61,8 +59,10 @@ class ShareListView extends React.Component {
needsPermission: isAndroid || false needsPermission: isAndroid || false
}; };
this.setHeader(); this.setHeader();
this.unsubscribeFocus = props.navigation.addListener('focus', () => BackHandler.addEventListener('hardwareBackPress', this.handleBackPress)); if (isAndroid) {
this.unsubscribeBlur = props.navigation.addListener('blur', () => BackHandler.removeEventListener('hardwareBackPress', this.handleBackPress)); this.unsubscribeFocus = props.navigation.addListener('focus', () => BackHandler.addEventListener('hardwareBackPress', this.handleBackPress));
this.unsubscribeBlur = props.navigation.addListener('blur', () => BackHandler.removeEventListener('hardwareBackPress', this.handleBackPress));
}
} }
async componentDidMount() { async componentDidMount() {
@ -108,20 +108,19 @@ class ShareListView extends React.Component {
return true; return true;
} }
const { server, theme, userId } = this.props; const { server, userId } = this.props;
if (server !== nextProps.server) { if (server !== nextProps.server) {
return true; return true;
} }
if (userId !== nextProps.userId) { if (userId !== nextProps.userId) {
return true; return true;
} }
if (theme !== nextProps.theme) {
return true;
}
const { searchResults } = this.state; const { searchResults } = this.state;
if (!isEqual(nextState.searchResults, searchResults)) { if (nextState.searching) {
return true; if (!isEqual(nextState.searchResults, searchResults)) {
return true;
}
} }
return false; return false;
} }
@ -189,7 +188,7 @@ class ShareListView extends React.Component {
this.setState(...args); this.setState(...args);
} }
query = (text) => { query = async(text) => {
const db = database.active; const db = database.active;
const defaultWhereClause = [ const defaultWhereClause = [
Q.where('archived', false), Q.where('archived', false),
@ -200,26 +199,35 @@ class ShareListView extends React.Component {
]; ];
if (text) { if (text) {
const likeString = sanitizeLikeString(text); const likeString = sanitizeLikeString(text);
return db.collections defaultWhereClause.push(
.get('subscriptions') Q.or(
.query( Q.where('name', Q.like(`%${ likeString }%`)),
...defaultWhereClause, Q.where('fname', Q.like(`%${ likeString }%`))
Q.or( )
Q.where('name', Q.like(`%${ likeString }%`)), );
Q.where('fname', Q.like(`%${ likeString }%`))
)
).fetch();
} }
return db.collections.get('subscriptions').query(...defaultWhereClause).fetch(); const data = await db.collections.get('subscriptions').query(...defaultWhereClause).fetch();
return data.map(item => ({
rid: item.rid,
t: item.t,
name: item.name,
fname: item.fname,
blocked: item.blocked,
blocker: item.blocker,
prid: item.prid,
uids: item.uids,
usernames: item.usernames,
topic: item.topic
}));
} }
getSubscriptions = async(server) => { getSubscriptions = async(server) => {
const serversDB = database.servers; const serversDB = database.servers;
if (server) { if (server) {
this.chats = await this.query(); const chats = await this.query();
const serversCollection = serversDB.collections.get('servers'); const serversCollection = serversDB.collections.get('servers');
this.servers = await serversCollection.query().fetch(); const serversCount = await serversCollection.query(Q.where('rooms_updated_at', Q.notEq(null))).fetchCount();
let serverInfo = {}; let serverInfo = {};
try { try {
serverInfo = await serversCollection.find(server); serverInfo = await serversCollection.find(server);
@ -228,8 +236,8 @@ class ShareListView extends React.Component {
} }
this.internalSetState({ this.internalSetState({
chats: this.chats ?? [], chats: chats ?? [],
servers: this.servers ?? [], serversCount,
loading: false, loading: false,
serverInfo serverInfo
}); });
@ -306,11 +314,14 @@ class ShareListView extends React.Component {
} }
return ( return (
<View style={[styles.headerContainer, { backgroundColor: themes[theme].auxiliaryBackground }]}> <>
<Text style={[styles.headerText, { color: themes[theme].titleText }]}> <View style={[styles.headerContainer, { backgroundColor: themes[theme].auxiliaryBackground }]}>
{I18n.t(header)} <Text style={[styles.headerText, { color: themes[theme].titleText }]}>
</Text> {I18n.t(header)}
</View> </Text>
</View>
<List.Separator />
</>
); );
} }
@ -353,41 +364,19 @@ class ShareListView extends React.Component {
); );
} }
renderSeparator = () => {
const { theme } = this.props;
return <View style={[styles.separator, { borderColor: themes[theme].separatorColor }]} />;
}
renderBorderBottom = () => {
const { theme } = this.props;
return <View style={[styles.borderBottom, { borderColor: themes[theme].separatorColor }]} />;
}
renderSelectServer = () => { renderSelectServer = () => {
const { servers } = this.state; const { serverInfo } = this.state;
const { server, theme, navigation } = this.props; const { navigation } = this.props;
const currentServer = servers.find(serverFiltered => serverFiltered.id === server); return (
return currentServer ? (
<> <>
{this.renderSectionHeader('Select_Server')} {this.renderSectionHeader('Select_Server')}
<View <ServerItem
style={[ onPress={() => navigation.navigate('SelectServerView')}
styles.bordered, item={serverInfo}
{ />
borderColor: themes[theme].separatorColor, <List.Separator />
backgroundColor: themes[theme].auxiliaryBackground
}
]}
>
<ServerItem
server={server}
onPress={() => navigation.navigate('SelectServerView', { servers: this.servers })}
item={currentServer}
theme={theme}
/>
</View>
</> </>
) : null; );
} }
renderEmptyComponent = () => { renderEmptyComponent = () => {
@ -400,23 +389,25 @@ class ShareListView extends React.Component {
} }
renderHeader = () => { renderHeader = () => {
const { searching } = this.state; const { searching, serversCount } = this.state;
if (searching) {
return null;
}
if (serversCount === 1) {
return this.renderSectionHeader('Chats');
}
return ( return (
<> <>
{ !searching {this.renderSelectServer()}
? ( {this.renderSectionHeader('Chats')}
<>
{this.renderSelectServer()}
{this.renderSectionHeader('Chats')}
</>
)
: null
}
</> </>
); );
} }
renderContent = () => { render = () => {
const { const {
chats, loading, searchResults, searching, searchText, needsPermission chats, loading, searchResults, searching, searchText, needsPermission
} = this.state; } = this.state;
@ -428,41 +419,34 @@ class ShareListView extends React.Component {
if (needsPermission) { if (needsPermission) {
return ( return (
<ScrollView <SafeAreaView>
style={{ backgroundColor: themes[theme].auxiliaryBackground }} <ScrollView
contentContainerStyle={[styles.container, styles.centered, { backgroundColor: themes[theme].backgroundColor }]} style={{ backgroundColor: themes[theme].backgroundColor }}
> contentContainerStyle={[styles.container, styles.centered, { backgroundColor: themes[theme].backgroundColor }]}
<Text style={[styles.permissionTitle, { color: themes[theme].titleText }]}>{permission.title}</Text> >
<Text style={[styles.permissionMessage, { color: themes[theme].bodyText }]}>{permission.message}</Text> <Text style={[styles.permissionTitle, { color: themes[theme].titleText }]}>{permission.title}</Text>
</ScrollView> <Text style={[styles.permissionMessage, { color: themes[theme].bodyText }]}>{permission.message}</Text>
</ScrollView>
</SafeAreaView>
); );
} }
return (
<FlatList
data={searching ? searchResults : chats}
keyExtractor={keyExtractor}
style={[styles.flatlist, { backgroundColor: themes[theme].auxiliaryBackground }]}
contentContainerStyle={{ backgroundColor: themes[theme].backgroundColor }}
renderItem={this.renderItem}
getItemLayout={getItemLayout}
ItemSeparatorComponent={this.renderSeparator}
ListHeaderComponent={this.renderHeader}
ListFooterComponent={!searching && this.renderBorderBottom}
ListHeaderComponentStyle={!searching ? { ...styles.borderBottom, borderColor: themes[theme].separatorColor } : {}}
ListEmptyComponent={searching && searchText ? this.renderEmptyComponent : null}
removeClippedSubviews
keyboardShouldPersistTaps='always'
initialNumToRender={12}
/>
);
}
render() {
return ( return (
<SafeAreaView> <SafeAreaView>
<StatusBar /> <FlatList
{this.renderContent()} data={searching ? searchResults : chats}
keyExtractor={keyExtractor}
style={[styles.flatlist, { backgroundColor: themes[theme].auxiliaryBackground }]}
contentContainerStyle={{ backgroundColor: themes[theme].backgroundColor }}
renderItem={this.renderItem}
getItemLayout={getItemLayout}
ItemSeparatorComponent={List.Separator}
ListHeaderComponent={this.renderHeader}
ListFooterComponent={!searching || searchResults.length > 0 ? <List.Separator /> : null}
ListEmptyComponent={searching && searchText ? this.renderEmptyComponent : null}
removeClippedSubviews
keyboardShouldPersistTaps='always'
/>
</SafeAreaView> </SafeAreaView>
); );
} }

View File

@ -14,6 +14,7 @@ import { THUMBS_HEIGHT } from './constants';
import sharedStyles from '../Styles'; import sharedStyles from '../Styles';
import { allowPreview } from './utils'; import { allowPreview } from './utils';
import I18n from '../../i18n'; import I18n from '../../i18n';
import { isAndroid } from '../../utils/deviceInfo';
const MESSAGEBOX_HEIGHT = 56; const MESSAGEBOX_HEIGHT = 56;
@ -63,7 +64,8 @@ const Preview = React.memo(({
const calculatedHeight = height - insets.top - insets.bottom - MESSAGEBOX_HEIGHT - thumbsHeight - headerHeight; const calculatedHeight = height - insets.top - insets.bottom - MESSAGEBOX_HEIGHT - thumbsHeight - headerHeight;
if (item?.canUpload) { if (item?.canUpload) {
if (type?.match(/video/)) { // Disable video preview on iOS to save memory
if (isAndroid && type?.match(/video/)) {
return ( return (
<ScrollView style={{ height: calculatedHeight }}> <ScrollView style={{ height: calculatedHeight }}>
<Video <Video
@ -81,8 +83,8 @@ const Preview = React.memo(({
} }
// Disallow preview of images too big in order to prevent memory issues on iOS share extension // Disallow preview of images too big in order to prevent memory issues on iOS share extension
if (allowPreview(isShareExtension, item?.size)) { if (type?.match(/image/)) {
if (type?.match(/image/)) { if (allowPreview(isShareExtension, item?.size)) {
return ( return (
<ImageViewer <ImageViewer
uri={item.path} uri={item.path}

View File

@ -90,18 +90,30 @@ const ThumbContent = React.memo(({ item, theme, isShareExtension }) => {
} }
if (type?.match(/video/)) { if (type?.match(/video/)) {
const { uri } = item; if (isIOS) {
return ( return (
<> <View style={[styles.thumb, { borderColor: themes[theme].borderColor }]}>
<Image source={{ uri }} style={styles.thumb} /> <CustomIcon
<CustomIcon name='camera'
name='camera-filled' size={30}
size={20} color={themes[theme].tintColor}
color={themes[theme].buttonText} />
style={styles.videoThumbIcon} </View>
/> );
</> } else {
); const { uri } = item;
return (
<>
<Image source={{ uri }} style={styles.thumb} />
<CustomIcon
name='camera-filled'
size={20}
color={themes[theme].buttonText}
style={styles.videoThumbIcon}
/>
</>
);
}
} }
// Multiple files upload of files different than image/video is not implemented, so there's no thumb // Multiple files upload of files different than image/video is not implemented, so there's no thumb

View File

@ -3,7 +3,6 @@ import PropTypes from 'prop-types';
import { View, Text, NativeModules } from 'react-native'; import { View, Text, NativeModules } from 'react-native';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import ShareExtension from 'rn-extensions-share'; import ShareExtension from 'rn-extensions-share';
import * as VideoThumbnails from 'expo-video-thumbnails';
import { themes } from '../../constants/colors'; import { themes } from '../../constants/colors';
import I18n from '../../i18n'; import I18n from '../../i18n';
@ -24,6 +23,7 @@ import { getUserSelector } from '../../selectors/login';
import StatusBar from '../../containers/StatusBar'; import StatusBar from '../../containers/StatusBar';
import database from '../../lib/database'; import database from '../../lib/database';
import { canUploadFile } from '../../utils/media'; import { canUploadFile } from '../../utils/media';
import { isAndroid } from '../../utils/deviceInfo';
class ShareView extends Component { class ShareView extends Component {
constructor(props) { constructor(props) {
@ -119,8 +119,9 @@ class ShareView extends Component {
item.error = error; item.error = error;
// get video thumbnails // get video thumbnails
if (item.mime?.match?.(/video/)) { if (isAndroid && this.files.length > 1 && item.mime?.match?.(/video/)) {
try { try {
const VideoThumbnails = require('expo-video-thumbnails');
const { uri } = await VideoThumbnails.getThumbnailAsync(item.path); const { uri } = await VideoThumbnails.getThumbnailAsync(item.path);
item.uri = uri; item.uri = uri;
} catch { } catch {

View File

@ -21,7 +21,41 @@ abstract_target 'defaults' do
end end
target 'ShareRocketChatRN' do target 'ShareRocketChatRN' do
all_pods pod 'EXAppleAuthentication', :path=> "../node_modules/expo-apple-authentication/ios"
pod 'EXAV', :path=> "../node_modules/expo-av/ios"
pod 'EXFileSystem', :path=> "../node_modules/expo-file-system/ios"
pod 'EXHaptics', :path=> "../node_modules/expo-haptics/ios"
pod 'EXImageLoader', :path=> "../node_modules/expo-image-loader/ios"
pod 'UMCore', :path=> "../node_modules/@unimodules/core/ios"
pod 'UMImageLoaderInterface', :path=> "../node_modules/unimodules-image-loader-interface/ios"
pod 'UMReactNativeAdapter', :path=> "../node_modules/@unimodules/react-native-adapter/ios"
use_react_native!(:path => '../node_modules/react-native')
pod 'RNFBApp', :path => '../node_modules/@react-native-firebase/app'
pod 'RNFBAnalytics', :path => '../node_modules/@react-native-firebase/analytics'
pod 'RNFBCrashlytics', :path => '../node_modules/@react-native-firebase/crashlytics'
pod 'RNCAsyncStorage', :path => '../node_modules/@react-native-community/async-storage'
pod 'RNCMaskedView', :path => '../node_modules/@react-native-community/masked-view'
pod 'RNFastImage', :path => '../node_modules/@rocket.chat/react-native-fast-image'
pod 'BugsnagReactNative', :path => '../node_modules/bugsnag-react-native'
pod 'react-native-appearance', :path => '../node_modules/react-native-appearance'
pod 'RNConfigReader', :path => '../node_modules/react-native-config-reader'
pod 'RNDeviceInfo', :path => '../node_modules/react-native-device-info'
pod 'react-native-document-picker', :path => '../node_modules/react-native-document-picker'
pod 'RNGestureHandler', :path => '../node_modules/react-native-gesture-handler'
pod 'RNLocalize', :path => '../node_modules/react-native-localize'
pod 'react-native-mmkv-storage', :path => '../node_modules/react-native-mmkv-storage'
pod 'RNReanimated', :path => '../node_modules/react-native-reanimated'
pod 'react-native-safe-area-context', :path => '../node_modules/react-native-safe-area-context'
pod 'RNScreens', :path => '../node_modules/react-native-screens'
pod 'react-native-simple-crypto', :path => '../node_modules/react-native-simple-crypto'
pod 'ReactNativeUiLib', :path => '../node_modules/react-native-ui-lib/lib'
pod 'RNVectorIcons', :path => '../node_modules/react-native-vector-icons'
pod 'rn-extensions-share', :path => '../node_modules/rn-extensions-share'
pod 'rn-fetch-blob', :path => '../node_modules/rn-fetch-blob'
pod 'RNRootView', :path => '../node_modules/rn-root-view'
pod 'react-native-orientation-locker', :path => '../node_modules/react-native-orientation-locker'
end end
# used to get user credentials # used to get user credentials

View File

@ -34,7 +34,7 @@ PODS:
- EXPermissions (9.0.1): - EXPermissions (9.0.1):
- UMCore - UMCore
- UMPermissionsInterface - UMPermissionsInterface
- EXVideoThumbnails (4.2.1): - EXVideoThumbnails (5.0.0):
- UMCore - UMCore
- UMFileSystemInterface - UMFileSystemInterface
- EXWebBrowser (8.3.1): - EXWebBrowser (8.3.1):
@ -895,7 +895,7 @@ SPEC CHECKSUMS:
EXKeepAwake: 8b0f68242f036b971f9f8976341823cbe6f50812 EXKeepAwake: 8b0f68242f036b971f9f8976341823cbe6f50812
EXLocalAuthentication: 985c65e08a6eb84f8f98b51f7435df138b18b9e8 EXLocalAuthentication: 985c65e08a6eb84f8f98b51f7435df138b18b9e8
EXPermissions: 80ac3acbdb145930079810fe5b08c022b3428aa8 EXPermissions: 80ac3acbdb145930079810fe5b08c022b3428aa8
EXVideoThumbnails: f70bdc5511749f3181028f5000bcb7be203c631d EXVideoThumbnails: 0be939563a5d46ce0d1fa9baea7d454b99475763
EXWebBrowser: d37a5ffdea1b65947352bc001dd9f732463725d4 EXWebBrowser: d37a5ffdea1b65947352bc001dd9f732463725d4
FBLazyVector: 3bb422f41b18121b71783a905c10e58606f7dc3e FBLazyVector: 3bb422f41b18121b71783a905c10e58606f7dc3e
FBReactNativeSpec: f2c97f2529dd79c083355182cc158c9f98f4bd6e FBReactNativeSpec: f2c97f2529dd79c083355182cc158c9f98f4bd6e
@ -1003,6 +1003,6 @@ SPEC CHECKSUMS:
Yoga: 4bd86afe9883422a7c4028c00e34790f560923d6 Yoga: 4bd86afe9883422a7c4028c00e34790f560923d6
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
PODFILE CHECKSUM: 8477bd3277dec7b3190105d922512e3791bc026f PODFILE CHECKSUM: 0351d0973911a397f1cb4e45f0b0f590b14816e3
COCOAPODS: 1.9.3 COCOAPODS: 1.9.3

View File

@ -1,20 +1,17 @@
{ {
"name": "EXVideoThumbnails", "name": "EXVideoThumbnails",
"version": "4.2.1", "version": "5.0.0",
"summary": "ExpoVideoThumbnails standalone module", "summary": "ExpoVideoThumbnails standalone module",
"description": "ExpoVideoThumbnails standalone module", "description": "ExpoVideoThumbnails standalone module",
"license": "MIT", "license": "MIT",
"authors": "650 Industries, Inc.", "authors": "650 Industries, Inc.",
"homepage": "https://github.com/expo/expo/tree/master/packages/expo-video-thumbnails", "homepage": "https://docs.expo.io/versions/latest/sdk/video-thumbnails/",
"platforms": { "platforms": {
"ios": "10.0" "ios": "11.0"
}, },
"source": { "source": {
"git": "https://github.com/expo/expo.git" "git": "https://github.com/expo/expo.git"
}, },
"source_files": "EXVideoThumbnails/**/*.{h,m}",
"preserve_paths": "EXVideoThumbnails/**/*.{h,m}",
"requires_arc": true,
"dependencies": { "dependencies": {
"UMCore": [ "UMCore": [
@ -22,5 +19,6 @@
"UMFileSystemInterface": [ "UMFileSystemInterface": [
] ]
} },
"source_files": "EXVideoThumbnails/**/*.{h,m}"
} }

View File

@ -34,7 +34,7 @@ PODS:
- EXPermissions (9.0.1): - EXPermissions (9.0.1):
- UMCore - UMCore
- UMPermissionsInterface - UMPermissionsInterface
- EXVideoThumbnails (4.2.1): - EXVideoThumbnails (5.0.0):
- UMCore - UMCore
- UMFileSystemInterface - UMFileSystemInterface
- EXWebBrowser (8.3.1): - EXWebBrowser (8.3.1):
@ -895,7 +895,7 @@ SPEC CHECKSUMS:
EXKeepAwake: 8b0f68242f036b971f9f8976341823cbe6f50812 EXKeepAwake: 8b0f68242f036b971f9f8976341823cbe6f50812
EXLocalAuthentication: 985c65e08a6eb84f8f98b51f7435df138b18b9e8 EXLocalAuthentication: 985c65e08a6eb84f8f98b51f7435df138b18b9e8
EXPermissions: 80ac3acbdb145930079810fe5b08c022b3428aa8 EXPermissions: 80ac3acbdb145930079810fe5b08c022b3428aa8
EXVideoThumbnails: f70bdc5511749f3181028f5000bcb7be203c631d EXVideoThumbnails: 0be939563a5d46ce0d1fa9baea7d454b99475763
EXWebBrowser: d37a5ffdea1b65947352bc001dd9f732463725d4 EXWebBrowser: d37a5ffdea1b65947352bc001dd9f732463725d4
FBLazyVector: 3bb422f41b18121b71783a905c10e58606f7dc3e FBLazyVector: 3bb422f41b18121b71783a905c10e58606f7dc3e
FBReactNativeSpec: f2c97f2529dd79c083355182cc158c9f98f4bd6e FBReactNativeSpec: f2c97f2529dd79c083355182cc158c9f98f4bd6e
@ -1003,6 +1003,6 @@ SPEC CHECKSUMS:
Yoga: 4bd86afe9883422a7c4028c00e34790f560923d6 Yoga: 4bd86afe9883422a7c4028c00e34790f560923d6
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
PODFILE CHECKSUM: 8477bd3277dec7b3190105d922512e3791bc026f PODFILE CHECKSUM: 0351d0973911a397f1cb4e45f0b0f590b14816e3
COCOAPODS: 1.9.3 COCOAPODS: 1.9.3

File diff suppressed because it is too large Load Diff

View File

@ -97,7 +97,6 @@ EOM
esac esac
} }
if [[ "$CONFIGURATION" == "Debug" ]]; then if [[ "$CONFIGURATION" == "Debug" ]]; then
install_resource "${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle"
install_resource "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/AntDesign.ttf" install_resource "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/AntDesign.ttf"
install_resource "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Entypo.ttf" install_resource "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Entypo.ttf"
install_resource "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/EvilIcons.ttf" install_resource "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/EvilIcons.ttf"
@ -115,10 +114,8 @@ if [[ "$CONFIGURATION" == "Debug" ]]; then
install_resource "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/SimpleLineIcons.ttf" install_resource "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/SimpleLineIcons.ttf"
install_resource "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Zocial.ttf" install_resource "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Zocial.ttf"
install_resource "${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle" install_resource "${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle"
install_resource "${PODS_CONFIGURATION_BUILD_DIR}/TOCropViewController/TOCropViewControllerBundle.bundle"
fi fi
if [[ "$CONFIGURATION" == "Release" ]]; then if [[ "$CONFIGURATION" == "Release" ]]; then
install_resource "${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle"
install_resource "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/AntDesign.ttf" install_resource "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/AntDesign.ttf"
install_resource "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Entypo.ttf" install_resource "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Entypo.ttf"
install_resource "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/EvilIcons.ttf" install_resource "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/EvilIcons.ttf"
@ -136,7 +133,6 @@ if [[ "$CONFIGURATION" == "Release" ]]; then
install_resource "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/SimpleLineIcons.ttf" install_resource "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/SimpleLineIcons.ttf"
install_resource "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Zocial.ttf" install_resource "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Zocial.ttf"
install_resource "${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle" install_resource "${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle"
install_resource "${PODS_CONFIGURATION_BUILD_DIR}/TOCropViewController/TOCropViewControllerBundle.bundle"
fi fi
mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -59,7 +59,7 @@
"expo-haptics": "8.2.1", "expo-haptics": "8.2.1",
"expo-keep-awake": "8.2.1", "expo-keep-awake": "8.2.1",
"expo-local-authentication": "9.2.0", "expo-local-authentication": "9.2.0",
"expo-video-thumbnails": "4.2.1", "expo-video-thumbnails": "^5.0.0",
"expo-web-browser": "8.3.1", "expo-web-browser": "8.3.1",
"hoist-non-react-statics": "3.3.2", "hoist-non-react-statics": "3.3.2",
"i18n-js": "3.7.1", "i18n-js": "3.7.1",

View File

@ -6849,10 +6849,10 @@ expo-permissions@~9.0.1:
resolved "https://registry.yarnpkg.com/expo-permissions/-/expo-permissions-9.0.1.tgz#dc10b58654bbe39bbbed5827369942b01b08055e" resolved "https://registry.yarnpkg.com/expo-permissions/-/expo-permissions-9.0.1.tgz#dc10b58654bbe39bbbed5827369942b01b08055e"
integrity sha512-CosJgy8XQRN/OFG2JTQDcFxz3XTGi27coCMym/hVXWtQfk0z6PwdRG5IXHfLGuSckwIcgmirrwm2+Zc0X3MmNg== integrity sha512-CosJgy8XQRN/OFG2JTQDcFxz3XTGi27coCMym/hVXWtQfk0z6PwdRG5IXHfLGuSckwIcgmirrwm2+Zc0X3MmNg==
expo-video-thumbnails@4.2.1: expo-video-thumbnails@^5.0.0:
version "4.2.1" version "5.0.0"
resolved "https://registry.yarnpkg.com/expo-video-thumbnails/-/expo-video-thumbnails-4.2.1.tgz#8867ecf143acbca6425da05d97beaa0cd31b2bc2" resolved "https://registry.yarnpkg.com/expo-video-thumbnails/-/expo-video-thumbnails-5.0.0.tgz#819adcf2e79d774a4f0d70da200bf053e07cd059"
integrity sha512-HxnK/AzGHXNWCB0GnTLXDnk76Nv/MgId1XgrxuESsPFkzUptxhRsMadD/27Diny37Ele2MZVAjID25ZMbs8N5A== integrity sha512-jYmpuKzGn4i4O52TkLiVm4/06VrGyJWXSuU99zAdN5N//8J0aA8MzC3nxk+PKQcHGj36enOPT5P5aHARFbtVww==
expo-web-browser@8.3.1: expo-web-browser@8.3.1:
version "8.3.1" version "8.3.1"
@ -13189,7 +13189,7 @@ react-native-windows@^0.62.0-0:
uuid "^3.3.2" uuid "^3.3.2"
xml-parser "^1.2.1" xml-parser "^1.2.1"
react-native@RocketChat/react-native#0.63.4: react-native@RocketChat/react-native#0.63.4, react-native@^0.63.1:
version "0.63.4" version "0.63.4"
resolved "https://codeload.github.com/RocketChat/react-native/tar.gz/616299bbc01eeb56cb7d5b52e543051e1ad2d136" resolved "https://codeload.github.com/RocketChat/react-native/tar.gz/616299bbc01eeb56cb7d5b52e543051e1ad2d136"
dependencies: dependencies:
@ -13832,6 +13832,8 @@ ripemd160@^2.0.0, ripemd160@^2.0.1:
rn-extensions-share@RocketChat/rn-extensions-share: rn-extensions-share@RocketChat/rn-extensions-share:
version "2.4.1" version "2.4.1"
resolved "https://codeload.github.com/RocketChat/rn-extensions-share/tar.gz/4d7c0e4c2f300e4fb116af7b7cc0dbbc8169150c" resolved "https://codeload.github.com/RocketChat/rn-extensions-share/tar.gz/4d7c0e4c2f300e4fb116af7b7cc0dbbc8169150c"
dependencies:
react-native "^0.63.1"
rn-fetch-blob@0.12.0: rn-fetch-blob@0.12.0:
version "0.12.0" version "0.12.0"