MM-15758 Update dependencies including Fastlane (#4272)
* Update dependencies including Fastlane and disable Flipper on iOS * Remove EventEmitter for previous doc-viewer * Fix android crash when setting more channels buttons * Downgrade fuse.js * Upgrade deps to latest * Update Podfile.lock * Downgrade RNN to 6.4.0 * QA Review #2 * Upgrade fuse.js to 6.0.0
This commit is contained in:
parent
a0841e0ef1
commit
d3a6e166ad
95 changed files with 5203 additions and 5372 deletions
45
NOTICE.txt
45
NOTICE.txt
|
|
@ -1430,20 +1430,20 @@ THE SOFTWARE.
|
|||
|
||||
---
|
||||
|
||||
## react-native-cookies
|
||||
## @react-native-community/cookies
|
||||
|
||||
This product contains 'react-native-cookies' by @joeferraro.
|
||||
This product contains '@react-native-community/cookies' by @joeferraro.
|
||||
|
||||
Cookie manager for react native
|
||||
|
||||
* HOMEPAGE:
|
||||
* https://github.com/joeferraro/react-native-cookies
|
||||
* https://github.com/react-native-community/cookies
|
||||
|
||||
* LICENSE: MIT
|
||||
|
||||
The MIT License (MIT)
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2015 Joseph P. Ferraro
|
||||
Copyright (c) 2020 React Native Community
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
@ -1500,41 +1500,6 @@ SOFTWARE.
|
|||
|
||||
---
|
||||
|
||||
## react-native-doc-viewer
|
||||
|
||||
This product contains 'react-native-doc-viewer' by Philipp Hecht.
|
||||
|
||||
React Native Native Module Bridge Quicklock Document Viewer for IOS + Android supports pdf, png, jpg, xls, ppt, doc, docx, pptx, xlx + Video Player mp4 supported
|
||||
|
||||
* HOMEPAGE:
|
||||
* https://github.com/philipphecht/react-native-doc-viewer/blob/master/README.md
|
||||
|
||||
* LICENSE: MIT
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 Phil Pike
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
---
|
||||
|
||||
## react-native-document-picker
|
||||
|
||||
This product contains 'react-native-document-picker' by Elyx0.
|
||||
|
|
|
|||
|
|
@ -5,8 +5,9 @@ import android.content.Context;
|
|||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.oblador.keychain.KeychainModule;
|
||||
|
||||
import com.mattermost.react_native_interface.ResolvePromise;
|
||||
|
|
@ -35,7 +36,12 @@ public class MattermostCredentialsHelper {
|
|||
|
||||
HashMap<String, String> asyncStorageResults = asyncStorage.multiGet(asyncStorageKeys);
|
||||
String serverUrl = asyncStorageResults.get(CURRENT_SERVER_URL);
|
||||
final WritableMap options = Arguments.createMap();
|
||||
final WritableMap authPrompt = Arguments.createMap();
|
||||
authPrompt.putString("title", "Authenticate to retrieve secret");
|
||||
authPrompt.putString("cancel", "Cancel");
|
||||
options.putMap("authenticationPrompt", authPrompt);
|
||||
|
||||
keychainModule.getGenericPasswordForOptions(serverUrl, promise);
|
||||
keychainModule.getInternetCredentialsForServer(serverUrl, options, promise);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ const MOCK_CHANNEL_MARK_AS_READ = 'MOCK_CHANNEL_MARK_AS_READ';
|
|||
const MOCK_CHANNEL_MARK_AS_VIEWED = 'MOCK_CHANNEL_MARK_AS_VIEWED';
|
||||
|
||||
jest.mock('@mm-redux/actions/channels', () => {
|
||||
const channelActions = require.requireActual('@mm-redux/actions/channels');
|
||||
const channelActions = jest.requireActual('../../mm-redux/actions/channels');
|
||||
return {
|
||||
...channelActions,
|
||||
markChannelAsRead: jest.fn().mockReturnValue({type: 'MOCK_CHANNEL_MARK_AS_READ'}),
|
||||
|
|
@ -31,7 +31,7 @@ jest.mock('@mm-redux/actions/channels', () => {
|
|||
});
|
||||
|
||||
jest.mock('@mm-redux/selectors/entities/teams', () => {
|
||||
const teamSelectors = require.requireActual('@mm-redux/selectors/entities/teams');
|
||||
const teamSelectors = jest.requireActual('../../mm-redux/selectors/entities/teams');
|
||||
return {
|
||||
...teamSelectors,
|
||||
getTeamByName: jest.fn(() => ({name: 'current-team-name'})),
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import {getCurrentUserId} from '@mm-redux/selectors/entities/users';
|
|||
|
||||
import {setAppCredentials} from 'app/init/credentials';
|
||||
import PushNotifications from 'app/push_notifications';
|
||||
import {getDeviceTimezoneAsync} from 'app/utils/timezone';
|
||||
import {getDeviceTimezone} from 'app/utils/timezone';
|
||||
import {setCSRFFromCookie} from 'app/utils/security';
|
||||
import {loadConfigAndLicense} from 'app/actions/views/root';
|
||||
|
||||
|
|
@ -35,7 +35,7 @@ export function handleSuccessfulLogin() {
|
|||
|
||||
const enableTimezone = isTimezoneEnabled(state);
|
||||
if (enableTimezone) {
|
||||
const timezone = await getDeviceTimezoneAsync();
|
||||
const timezone = getDeviceTimezone();
|
||||
dispatch(autoUpdateTimezone(timezone));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,21 +12,6 @@ jest.mock('app/init/credentials', () => ({
|
|||
setAppCredentials: () => jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('react-native-cookies', () => ({
|
||||
addEventListener: jest.fn(),
|
||||
removeEventListener: jest.fn(),
|
||||
openURL: jest.fn(),
|
||||
canOpenURL: jest.fn(),
|
||||
getInitialURL: jest.fn(),
|
||||
get: () => Promise.resolve(({
|
||||
res: {
|
||||
MMCSRF: {
|
||||
value: 'the cookie',
|
||||
},
|
||||
},
|
||||
})),
|
||||
}));
|
||||
|
||||
const mockStore = configureStore([thunk]);
|
||||
|
||||
describe('Actions.Views.Login', () => {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
/* eslint-disable no-import-assign */
|
||||
|
||||
import configureStore from 'redux-mock-store';
|
||||
import thunk from 'redux-thunk';
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import {getCurrentUserId, getStatusForUserId} from '@mm-redux/selectors/entities
|
|||
|
||||
import {setAppCredentials} from 'app/init/credentials';
|
||||
import {setCSRFFromCookie} from '@utils/security';
|
||||
import {getDeviceTimezoneAsync} from '@utils/timezone';
|
||||
import {getDeviceTimezone} from '@utils/timezone';
|
||||
|
||||
const HTTP_UNAUTHORIZED = 401;
|
||||
|
||||
|
|
@ -34,7 +34,7 @@ export function completeLogin(user, deviceToken) {
|
|||
// Set timezone
|
||||
const enableTimezone = isTimezoneEnabled(state);
|
||||
if (enableTimezone) {
|
||||
const timezone = await getDeviceTimezoneAsync();
|
||||
const timezone = getDeviceTimezone();
|
||||
dispatch(autoUpdateTimezone(timezone));
|
||||
}
|
||||
|
||||
|
|
@ -240,4 +240,5 @@ export function setCurrentUserStatusOffline() {
|
|||
};
|
||||
}
|
||||
|
||||
/* eslint-disable no-import-assign */
|
||||
HelperActions.forceLogoutIfNecessary = forceLogoutIfNecessary;
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
/* eslint-disable no-import-assign */
|
||||
|
||||
import assert from 'assert';
|
||||
import nock from 'nock';
|
||||
import {Server, WebSocket as MockWebSocket} from 'mock-socket';
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ class WebSocketClient {
|
|||
this.connectFailCount = 0;
|
||||
this.sequence = 1;
|
||||
if (this.conn && this.conn.readyState === WebSocket.OPEN) {
|
||||
this.conn.onclose = () => {}; //eslint-disable-line no-empty-function
|
||||
this.conn.onclose = () => {}; //eslint-disable-line @typescript-eslint/no-empty-function
|
||||
this.conn.close();
|
||||
this.conn = undefined;
|
||||
console.log('websocket closed'); //eslint-disable-line no-console
|
||||
|
|
|
|||
|
|
@ -9,17 +9,27 @@ import {
|
|||
Text,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import Fuse from 'fuse.js';
|
||||
|
||||
import AutocompleteDivider from 'app/components/autocomplete/autocomplete_divider';
|
||||
import Emoji from 'app/components/emoji';
|
||||
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
|
||||
import {BuiltInEmojis} from 'app/utils/emojis';
|
||||
import {getEmojiByName, compareEmojis} from 'app/utils/emoji_utils';
|
||||
import {makeStyleSheetFromTheme} from 'app/utils/theme';
|
||||
import AutocompleteDivider from '@components/autocomplete/autocomplete_divider';
|
||||
import Emoji from '@components/emoji';
|
||||
import TouchableWithFeedback from '@components/touchable_with_feedback';
|
||||
import {BuiltInEmojis} from '@utils/emojis';
|
||||
import {getEmojiByName, compareEmojis} from '@utils/emoji_utils';
|
||||
import {makeStyleSheetFromTheme} from '@utils/theme';
|
||||
|
||||
const EMOJI_REGEX = /(^|\s|^\+|^-)(:([^:\s]*))$/i;
|
||||
const EMOJI_REGEX_WITHOUT_PREFIX = /\B(:([^:\s]*))$/i;
|
||||
|
||||
const options = {
|
||||
shouldSort: true,
|
||||
threshold: 0.3,
|
||||
location: 0,
|
||||
distance: 100,
|
||||
minMatchCharLength: 2,
|
||||
maxPatternLength: 32,
|
||||
};
|
||||
|
||||
export default class EmojiSuggestion extends PureComponent {
|
||||
static propTypes = {
|
||||
actions: PropTypes.shape({
|
||||
|
|
@ -30,7 +40,6 @@ export default class EmojiSuggestion extends PureComponent {
|
|||
customEmojisEnabled: PropTypes.bool,
|
||||
emojis: PropTypes.array.isRequired,
|
||||
isSearch: PropTypes.bool,
|
||||
fuse: PropTypes.object.isRequired,
|
||||
maxListHeight: PropTypes.number,
|
||||
theme: PropTypes.object.isRequired,
|
||||
onChangeText: PropTypes.func.isRequired,
|
||||
|
|
@ -54,64 +63,38 @@ export default class EmojiSuggestion extends PureComponent {
|
|||
super(props);
|
||||
|
||||
this.matchTerm = '';
|
||||
const list = props.emojis || [];
|
||||
this.fuse = new Fuse(list, options);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (nextProps.isSearch) {
|
||||
componentDidUpdate(prevProps) {
|
||||
if (this.props.isSearch) {
|
||||
return;
|
||||
}
|
||||
|
||||
const regex = EMOJI_REGEX;
|
||||
const match = nextProps.value.substring(0, nextProps.cursorPosition).match(regex);
|
||||
const {cursorPosition, emojis, value} = this.props;
|
||||
const match = value.substring(0, cursorPosition).match(EMOJI_REGEX);
|
||||
|
||||
if (prevProps.emojis !== emojis) {
|
||||
const list = emojis || [];
|
||||
this.fuse = new Fuse(list, options);
|
||||
}
|
||||
|
||||
if (!match || this.state.emojiComplete) {
|
||||
this.setState({
|
||||
active: false,
|
||||
emojiComplete: false,
|
||||
});
|
||||
|
||||
this.props.onResultCountChange(0);
|
||||
|
||||
this.resetAutocomplete();
|
||||
return;
|
||||
}
|
||||
|
||||
const oldMatchTerm = this.matchTerm;
|
||||
this.matchTerm = match[3] || '';
|
||||
|
||||
if (this.matchTerm !== oldMatchTerm && this.matchTerm.length && nextProps.customEmojisEnabled) {
|
||||
this.props.actions.autocompleteCustomEmojis(this.matchTerm);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.matchTerm.length) {
|
||||
this.handleFuzzySearch(this.matchTerm, nextProps);
|
||||
} else {
|
||||
this.setEmojiData(nextProps.emojis);
|
||||
if (this.matchTerm !== oldMatchTerm || match[2] === ':') {
|
||||
if (this.props.customEmojisEnabled) {
|
||||
this.props.actions.autocompleteCustomEmojis(this.matchTerm);
|
||||
}
|
||||
this.searchEmoji(this.matchTerm);
|
||||
}
|
||||
}
|
||||
|
||||
handleFuzzySearch = (matchTerm, props) => {
|
||||
const {emojis, fuse} = props;
|
||||
|
||||
const results = fuse.search(matchTerm.toLowerCase());
|
||||
const data = results.map((index) => emojis[index]);
|
||||
this.setEmojiData(data, matchTerm);
|
||||
};
|
||||
|
||||
setEmojiData = (data, matchTerm = null) => {
|
||||
let sorter = compareEmojis;
|
||||
if (matchTerm) {
|
||||
sorter = (a, b) => compareEmojis(a, b, matchTerm);
|
||||
}
|
||||
|
||||
this.setState({
|
||||
active: data.length > 0,
|
||||
dataSource: data.sort(sorter),
|
||||
});
|
||||
|
||||
this.props.onResultCountChange(data.length);
|
||||
};
|
||||
|
||||
completeSuggestion = (emoji) => {
|
||||
const {actions, cursorPosition, onChangeText, value, rootId} = this.props;
|
||||
const emojiPart = value.substring(0, cursorPosition);
|
||||
|
|
@ -160,6 +143,19 @@ export default class EmojiSuggestion extends PureComponent {
|
|||
});
|
||||
};
|
||||
|
||||
getItemLayout = ({index}) => ({length: 40, offset: 40 * index, index})
|
||||
|
||||
handleFuzzySearch = (matchTerm) => {
|
||||
const {emojis} = this.props;
|
||||
|
||||
clearTimeout(this.searchTermTimeout);
|
||||
this.searchTermTimeout = setTimeout(() => {
|
||||
const results = this.fuse.search(matchTerm.toLowerCase()).map((r) => r.refIndex);
|
||||
const data = results.map((index) => emojis[index]);
|
||||
this.setEmojiData(data, matchTerm);
|
||||
}, 100);
|
||||
};
|
||||
|
||||
keyExtractor = (item) => item;
|
||||
|
||||
renderItem = ({item}) => {
|
||||
|
|
@ -183,7 +179,36 @@ export default class EmojiSuggestion extends PureComponent {
|
|||
);
|
||||
};
|
||||
|
||||
getItemLayout = ({index}) => ({length: 40, offset: 40 * index, index})
|
||||
resetAutocomplete = () => {
|
||||
this.setState({
|
||||
active: false,
|
||||
emojiComplete: false,
|
||||
});
|
||||
|
||||
this.props.onResultCountChange(0);
|
||||
}
|
||||
|
||||
searchEmoji = (matchTerm) => {
|
||||
if (matchTerm.length) {
|
||||
this.handleFuzzySearch(matchTerm);
|
||||
} else {
|
||||
this.setEmojiData(this.props.emojis);
|
||||
}
|
||||
}
|
||||
|
||||
setEmojiData = (data, matchTerm = null) => {
|
||||
let sorter = compareEmojis;
|
||||
if (matchTerm) {
|
||||
sorter = (a, b) => compareEmojis(a, b, matchTerm);
|
||||
}
|
||||
|
||||
this.setState({
|
||||
active: data.length > 0,
|
||||
dataSource: data.sort(sorter),
|
||||
});
|
||||
|
||||
this.props.onResultCountChange(data.length);
|
||||
};
|
||||
|
||||
render() {
|
||||
const {maxListHeight, theme, nestedScrollEnabled} = this.props;
|
||||
|
|
|
|||
|
|
@ -2,21 +2,20 @@
|
|||
// See LICENSE.txt for license information.
|
||||
|
||||
import {connect} from 'react-redux';
|
||||
import {createSelector} from 'reselect';
|
||||
import {bindActionCreators} from 'redux';
|
||||
|
||||
import {getCustomEmojisByName} from '@mm-redux/selectors/entities/emojis';
|
||||
import {getConfig} from '@mm-redux/selectors/entities/general';
|
||||
import {autocompleteCustomEmojis} from '@mm-redux/actions/emojis';
|
||||
import {createIdsSelector} from '@mm-redux/utils/helpers';
|
||||
|
||||
import {addReactionToLatestPost} from 'app/actions/views/emoji';
|
||||
import {getTheme} from '@mm-redux/selectors/entities/preferences';
|
||||
import {EmojiIndicesByAlias} from 'app/utils/emojis';
|
||||
|
||||
import EmojiSuggestion from './emoji_suggestion';
|
||||
import Fuse from 'fuse.js';
|
||||
|
||||
const getEmojisByName = createSelector(
|
||||
const getEmojisByName = createIdsSelector(
|
||||
getCustomEmojisByName,
|
||||
(customEmojis) => {
|
||||
const emoticons = new Set();
|
||||
|
|
@ -29,23 +28,11 @@ const getEmojisByName = createSelector(
|
|||
);
|
||||
|
||||
function mapStateToProps(state) {
|
||||
const options = {
|
||||
shouldSort: true,
|
||||
threshold: 0.3,
|
||||
location: 0,
|
||||
distance: 100,
|
||||
minMatchCharLength: 2,
|
||||
maxPatternLength: 32,
|
||||
};
|
||||
|
||||
const emojis = getEmojisByName(state);
|
||||
const list = emojis.length ? emojis : [];
|
||||
const fuse = new Fuse(list, options);
|
||||
|
||||
return {
|
||||
emojis,
|
||||
customEmojisEnabled: getConfig(state).EnableCustomEmoji === 'true',
|
||||
fuse,
|
||||
theme: getTheme(state),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,14 +5,14 @@ import React from 'react';
|
|||
import {shallow} from 'enzyme';
|
||||
import {Text} from 'react-native';
|
||||
|
||||
import {alertErrorWithFallback} from 'app/utils/general';
|
||||
import {alertErrorWithFallback} from '@utils/general';
|
||||
|
||||
import ChannelLink from './channel_link';
|
||||
|
||||
jest.mock('react-intl');
|
||||
|
||||
jest.mock('app/utils/general', () => {
|
||||
const general = require.requireActual('app/utils/general');
|
||||
jest.mock('@utils/general', () => {
|
||||
const general = jest.requireActual('../../utils/general');
|
||||
return {
|
||||
...general,
|
||||
alertErrorWithFallback: jest.fn(),
|
||||
|
|
|
|||
|
|
@ -17,13 +17,12 @@ exports[`ChannelLoader should match snapshot 1`] = `
|
|||
]
|
||||
}
|
||||
>
|
||||
<ForwardRef(AnimatedComponentWrapper)
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"backgroundColor": "#ffffff",
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"marginVertical": 10,
|
||||
"paddingLeft": 12,
|
||||
"paddingRight": 20,
|
||||
|
|
@ -31,30 +30,39 @@ exports[`ChannelLoader should match snapshot 1`] = `
|
|||
Object {
|
||||
"backgroundColor": "#ffffff",
|
||||
},
|
||||
Object {
|
||||
"opacity": 0.6,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<ImageContent
|
||||
animate="fade"
|
||||
color="rgba(61,60,64,0.15)"
|
||||
firstLineWidth="80%"
|
||||
hasRadius={true}
|
||||
lineNumber={3}
|
||||
lineSpacing={5}
|
||||
size={32}
|
||||
textSize={14}
|
||||
/>
|
||||
</ForwardRef(AnimatedComponentWrapper)>
|
||||
<ForwardRef(AnimatedComponentWrapper)
|
||||
<UNDEFINED
|
||||
Animation={[Function]}
|
||||
Left={[Function]}
|
||||
styles={
|
||||
Object {
|
||||
"left": Object {
|
||||
"color": "rgba(61,60,64,0.15)",
|
||||
},
|
||||
}
|
||||
}
|
||||
>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
/>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
width={80}
|
||||
/>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
width={60}
|
||||
/>
|
||||
</UNDEFINED>
|
||||
</View>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"backgroundColor": "#ffffff",
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"marginVertical": 10,
|
||||
"paddingLeft": 12,
|
||||
"paddingRight": 20,
|
||||
|
|
@ -62,30 +70,39 @@ exports[`ChannelLoader should match snapshot 1`] = `
|
|||
Object {
|
||||
"backgroundColor": "#ffffff",
|
||||
},
|
||||
Object {
|
||||
"opacity": 0.6,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<ImageContent
|
||||
animate="fade"
|
||||
color="rgba(61,60,64,0.15)"
|
||||
firstLineWidth="80%"
|
||||
hasRadius={true}
|
||||
lineNumber={3}
|
||||
lineSpacing={5}
|
||||
size={32}
|
||||
textSize={14}
|
||||
/>
|
||||
</ForwardRef(AnimatedComponentWrapper)>
|
||||
<ForwardRef(AnimatedComponentWrapper)
|
||||
<UNDEFINED
|
||||
Animation={[Function]}
|
||||
Left={[Function]}
|
||||
styles={
|
||||
Object {
|
||||
"left": Object {
|
||||
"color": "rgba(61,60,64,0.15)",
|
||||
},
|
||||
}
|
||||
}
|
||||
>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
/>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
width={80}
|
||||
/>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
width={60}
|
||||
/>
|
||||
</UNDEFINED>
|
||||
</View>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"backgroundColor": "#ffffff",
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"marginVertical": 10,
|
||||
"paddingLeft": 12,
|
||||
"paddingRight": 20,
|
||||
|
|
@ -93,30 +110,39 @@ exports[`ChannelLoader should match snapshot 1`] = `
|
|||
Object {
|
||||
"backgroundColor": "#ffffff",
|
||||
},
|
||||
Object {
|
||||
"opacity": 0.6,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<ImageContent
|
||||
animate="fade"
|
||||
color="rgba(61,60,64,0.15)"
|
||||
firstLineWidth="80%"
|
||||
hasRadius={true}
|
||||
lineNumber={3}
|
||||
lineSpacing={5}
|
||||
size={32}
|
||||
textSize={14}
|
||||
/>
|
||||
</ForwardRef(AnimatedComponentWrapper)>
|
||||
<ForwardRef(AnimatedComponentWrapper)
|
||||
<UNDEFINED
|
||||
Animation={[Function]}
|
||||
Left={[Function]}
|
||||
styles={
|
||||
Object {
|
||||
"left": Object {
|
||||
"color": "rgba(61,60,64,0.15)",
|
||||
},
|
||||
}
|
||||
}
|
||||
>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
/>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
width={80}
|
||||
/>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
width={60}
|
||||
/>
|
||||
</UNDEFINED>
|
||||
</View>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"backgroundColor": "#ffffff",
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"marginVertical": 10,
|
||||
"paddingLeft": 12,
|
||||
"paddingRight": 20,
|
||||
|
|
@ -124,30 +150,39 @@ exports[`ChannelLoader should match snapshot 1`] = `
|
|||
Object {
|
||||
"backgroundColor": "#ffffff",
|
||||
},
|
||||
Object {
|
||||
"opacity": 0.6,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<ImageContent
|
||||
animate="fade"
|
||||
color="rgba(61,60,64,0.15)"
|
||||
firstLineWidth="80%"
|
||||
hasRadius={true}
|
||||
lineNumber={3}
|
||||
lineSpacing={5}
|
||||
size={32}
|
||||
textSize={14}
|
||||
/>
|
||||
</ForwardRef(AnimatedComponentWrapper)>
|
||||
<ForwardRef(AnimatedComponentWrapper)
|
||||
<UNDEFINED
|
||||
Animation={[Function]}
|
||||
Left={[Function]}
|
||||
styles={
|
||||
Object {
|
||||
"left": Object {
|
||||
"color": "rgba(61,60,64,0.15)",
|
||||
},
|
||||
}
|
||||
}
|
||||
>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
/>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
width={80}
|
||||
/>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
width={60}
|
||||
/>
|
||||
</UNDEFINED>
|
||||
</View>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"backgroundColor": "#ffffff",
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"marginVertical": 10,
|
||||
"paddingLeft": 12,
|
||||
"paddingRight": 20,
|
||||
|
|
@ -155,30 +190,39 @@ exports[`ChannelLoader should match snapshot 1`] = `
|
|||
Object {
|
||||
"backgroundColor": "#ffffff",
|
||||
},
|
||||
Object {
|
||||
"opacity": 0.6,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<ImageContent
|
||||
animate="fade"
|
||||
color="rgba(61,60,64,0.15)"
|
||||
firstLineWidth="80%"
|
||||
hasRadius={true}
|
||||
lineNumber={3}
|
||||
lineSpacing={5}
|
||||
size={32}
|
||||
textSize={14}
|
||||
/>
|
||||
</ForwardRef(AnimatedComponentWrapper)>
|
||||
<ForwardRef(AnimatedComponentWrapper)
|
||||
<UNDEFINED
|
||||
Animation={[Function]}
|
||||
Left={[Function]}
|
||||
styles={
|
||||
Object {
|
||||
"left": Object {
|
||||
"color": "rgba(61,60,64,0.15)",
|
||||
},
|
||||
}
|
||||
}
|
||||
>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
/>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
width={80}
|
||||
/>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
width={60}
|
||||
/>
|
||||
</UNDEFINED>
|
||||
</View>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"backgroundColor": "#ffffff",
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"marginVertical": 10,
|
||||
"paddingLeft": 12,
|
||||
"paddingRight": 20,
|
||||
|
|
@ -186,30 +230,39 @@ exports[`ChannelLoader should match snapshot 1`] = `
|
|||
Object {
|
||||
"backgroundColor": "#ffffff",
|
||||
},
|
||||
Object {
|
||||
"opacity": 0.6,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<ImageContent
|
||||
animate="fade"
|
||||
color="rgba(61,60,64,0.15)"
|
||||
firstLineWidth="80%"
|
||||
hasRadius={true}
|
||||
lineNumber={3}
|
||||
lineSpacing={5}
|
||||
size={32}
|
||||
textSize={14}
|
||||
/>
|
||||
</ForwardRef(AnimatedComponentWrapper)>
|
||||
<ForwardRef(AnimatedComponentWrapper)
|
||||
<UNDEFINED
|
||||
Animation={[Function]}
|
||||
Left={[Function]}
|
||||
styles={
|
||||
Object {
|
||||
"left": Object {
|
||||
"color": "rgba(61,60,64,0.15)",
|
||||
},
|
||||
}
|
||||
}
|
||||
>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
/>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
width={80}
|
||||
/>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
width={60}
|
||||
/>
|
||||
</UNDEFINED>
|
||||
</View>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"backgroundColor": "#ffffff",
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"marginVertical": 10,
|
||||
"paddingLeft": 12,
|
||||
"paddingRight": 20,
|
||||
|
|
@ -217,30 +270,39 @@ exports[`ChannelLoader should match snapshot 1`] = `
|
|||
Object {
|
||||
"backgroundColor": "#ffffff",
|
||||
},
|
||||
Object {
|
||||
"opacity": 0.6,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<ImageContent
|
||||
animate="fade"
|
||||
color="rgba(61,60,64,0.15)"
|
||||
firstLineWidth="80%"
|
||||
hasRadius={true}
|
||||
lineNumber={3}
|
||||
lineSpacing={5}
|
||||
size={32}
|
||||
textSize={14}
|
||||
/>
|
||||
</ForwardRef(AnimatedComponentWrapper)>
|
||||
<ForwardRef(AnimatedComponentWrapper)
|
||||
<UNDEFINED
|
||||
Animation={[Function]}
|
||||
Left={[Function]}
|
||||
styles={
|
||||
Object {
|
||||
"left": Object {
|
||||
"color": "rgba(61,60,64,0.15)",
|
||||
},
|
||||
}
|
||||
}
|
||||
>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
/>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
width={80}
|
||||
/>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
width={60}
|
||||
/>
|
||||
</UNDEFINED>
|
||||
</View>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"backgroundColor": "#ffffff",
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"marginVertical": 10,
|
||||
"paddingLeft": 12,
|
||||
"paddingRight": 20,
|
||||
|
|
@ -248,30 +310,39 @@ exports[`ChannelLoader should match snapshot 1`] = `
|
|||
Object {
|
||||
"backgroundColor": "#ffffff",
|
||||
},
|
||||
Object {
|
||||
"opacity": 0.6,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<ImageContent
|
||||
animate="fade"
|
||||
color="rgba(61,60,64,0.15)"
|
||||
firstLineWidth="80%"
|
||||
hasRadius={true}
|
||||
lineNumber={3}
|
||||
lineSpacing={5}
|
||||
size={32}
|
||||
textSize={14}
|
||||
/>
|
||||
</ForwardRef(AnimatedComponentWrapper)>
|
||||
<ForwardRef(AnimatedComponentWrapper)
|
||||
<UNDEFINED
|
||||
Animation={[Function]}
|
||||
Left={[Function]}
|
||||
styles={
|
||||
Object {
|
||||
"left": Object {
|
||||
"color": "rgba(61,60,64,0.15)",
|
||||
},
|
||||
}
|
||||
}
|
||||
>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
/>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
width={80}
|
||||
/>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
width={60}
|
||||
/>
|
||||
</UNDEFINED>
|
||||
</View>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"backgroundColor": "#ffffff",
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"marginVertical": 10,
|
||||
"paddingLeft": 12,
|
||||
"paddingRight": 20,
|
||||
|
|
@ -279,30 +350,39 @@ exports[`ChannelLoader should match snapshot 1`] = `
|
|||
Object {
|
||||
"backgroundColor": "#ffffff",
|
||||
},
|
||||
Object {
|
||||
"opacity": 0.6,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<ImageContent
|
||||
animate="fade"
|
||||
color="rgba(61,60,64,0.15)"
|
||||
firstLineWidth="80%"
|
||||
hasRadius={true}
|
||||
lineNumber={3}
|
||||
lineSpacing={5}
|
||||
size={32}
|
||||
textSize={14}
|
||||
/>
|
||||
</ForwardRef(AnimatedComponentWrapper)>
|
||||
<ForwardRef(AnimatedComponentWrapper)
|
||||
<UNDEFINED
|
||||
Animation={[Function]}
|
||||
Left={[Function]}
|
||||
styles={
|
||||
Object {
|
||||
"left": Object {
|
||||
"color": "rgba(61,60,64,0.15)",
|
||||
},
|
||||
}
|
||||
}
|
||||
>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
/>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
width={80}
|
||||
/>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
width={60}
|
||||
/>
|
||||
</UNDEFINED>
|
||||
</View>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"backgroundColor": "#ffffff",
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"marginVertical": 10,
|
||||
"paddingLeft": 12,
|
||||
"paddingRight": 20,
|
||||
|
|
@ -310,30 +390,39 @@ exports[`ChannelLoader should match snapshot 1`] = `
|
|||
Object {
|
||||
"backgroundColor": "#ffffff",
|
||||
},
|
||||
Object {
|
||||
"opacity": 0.6,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<ImageContent
|
||||
animate="fade"
|
||||
color="rgba(61,60,64,0.15)"
|
||||
firstLineWidth="80%"
|
||||
hasRadius={true}
|
||||
lineNumber={3}
|
||||
lineSpacing={5}
|
||||
size={32}
|
||||
textSize={14}
|
||||
/>
|
||||
</ForwardRef(AnimatedComponentWrapper)>
|
||||
<ForwardRef(AnimatedComponentWrapper)
|
||||
<UNDEFINED
|
||||
Animation={[Function]}
|
||||
Left={[Function]}
|
||||
styles={
|
||||
Object {
|
||||
"left": Object {
|
||||
"color": "rgba(61,60,64,0.15)",
|
||||
},
|
||||
}
|
||||
}
|
||||
>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
/>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
width={80}
|
||||
/>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
width={60}
|
||||
/>
|
||||
</UNDEFINED>
|
||||
</View>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"backgroundColor": "#ffffff",
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"marginVertical": 10,
|
||||
"paddingLeft": 12,
|
||||
"paddingRight": 20,
|
||||
|
|
@ -341,30 +430,39 @@ exports[`ChannelLoader should match snapshot 1`] = `
|
|||
Object {
|
||||
"backgroundColor": "#ffffff",
|
||||
},
|
||||
Object {
|
||||
"opacity": 0.6,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<ImageContent
|
||||
animate="fade"
|
||||
color="rgba(61,60,64,0.15)"
|
||||
firstLineWidth="80%"
|
||||
hasRadius={true}
|
||||
lineNumber={3}
|
||||
lineSpacing={5}
|
||||
size={32}
|
||||
textSize={14}
|
||||
/>
|
||||
</ForwardRef(AnimatedComponentWrapper)>
|
||||
<ForwardRef(AnimatedComponentWrapper)
|
||||
<UNDEFINED
|
||||
Animation={[Function]}
|
||||
Left={[Function]}
|
||||
styles={
|
||||
Object {
|
||||
"left": Object {
|
||||
"color": "rgba(61,60,64,0.15)",
|
||||
},
|
||||
}
|
||||
}
|
||||
>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
/>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
width={80}
|
||||
/>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
width={60}
|
||||
/>
|
||||
</UNDEFINED>
|
||||
</View>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"backgroundColor": "#ffffff",
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"marginVertical": 10,
|
||||
"paddingLeft": 12,
|
||||
"paddingRight": 20,
|
||||
|
|
@ -372,30 +470,39 @@ exports[`ChannelLoader should match snapshot 1`] = `
|
|||
Object {
|
||||
"backgroundColor": "#ffffff",
|
||||
},
|
||||
Object {
|
||||
"opacity": 0.6,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<ImageContent
|
||||
animate="fade"
|
||||
color="rgba(61,60,64,0.15)"
|
||||
firstLineWidth="80%"
|
||||
hasRadius={true}
|
||||
lineNumber={3}
|
||||
lineSpacing={5}
|
||||
size={32}
|
||||
textSize={14}
|
||||
/>
|
||||
</ForwardRef(AnimatedComponentWrapper)>
|
||||
<ForwardRef(AnimatedComponentWrapper)
|
||||
<UNDEFINED
|
||||
Animation={[Function]}
|
||||
Left={[Function]}
|
||||
styles={
|
||||
Object {
|
||||
"left": Object {
|
||||
"color": "rgba(61,60,64,0.15)",
|
||||
},
|
||||
}
|
||||
}
|
||||
>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
/>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
width={80}
|
||||
/>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
width={60}
|
||||
/>
|
||||
</UNDEFINED>
|
||||
</View>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"backgroundColor": "#ffffff",
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"marginVertical": 10,
|
||||
"paddingLeft": 12,
|
||||
"paddingRight": 20,
|
||||
|
|
@ -403,22 +510,32 @@ exports[`ChannelLoader should match snapshot 1`] = `
|
|||
Object {
|
||||
"backgroundColor": "#ffffff",
|
||||
},
|
||||
Object {
|
||||
"opacity": 0.6,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<ImageContent
|
||||
animate="fade"
|
||||
color="rgba(61,60,64,0.15)"
|
||||
firstLineWidth="80%"
|
||||
hasRadius={true}
|
||||
lineNumber={3}
|
||||
lineSpacing={5}
|
||||
size={32}
|
||||
textSize={14}
|
||||
/>
|
||||
</ForwardRef(AnimatedComponentWrapper)>
|
||||
<UNDEFINED
|
||||
Animation={[Function]}
|
||||
Left={[Function]}
|
||||
styles={
|
||||
Object {
|
||||
"left": Object {
|
||||
"color": "rgba(61,60,64,0.15)",
|
||||
},
|
||||
}
|
||||
}
|
||||
>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
/>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
width={80}
|
||||
/>
|
||||
<UNDEFINED
|
||||
color="rgba(61,60,64,0.15)"
|
||||
width={60}
|
||||
/>
|
||||
</UNDEFINED>
|
||||
</View>
|
||||
</View>
|
||||
`;
|
||||
|
|
|
|||
|
|
@ -5,30 +5,32 @@ import React, {PureComponent} from 'react';
|
|||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
Animated,
|
||||
Easing,
|
||||
View,
|
||||
Dimensions,
|
||||
} from 'react-native';
|
||||
import {ImageContent} from 'rn-placeholder';
|
||||
|
||||
import EventEmitter from '@mm-redux/utils/event_emitter';
|
||||
import * as RNPlaceholder from 'rn-placeholder';
|
||||
|
||||
import CustomPropTypes from 'app/constants/custom_prop_types';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
|
||||
import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing';
|
||||
|
||||
const {View: AnimatedView} = Animated;
|
||||
|
||||
function calculateMaxRows(height) {
|
||||
return Math.round(height / 100);
|
||||
}
|
||||
|
||||
function Media(color) {
|
||||
return (
|
||||
<RNPlaceholder.PlaceholderMedia
|
||||
color={changeOpacity(color, 0.15)}
|
||||
isRound={true}
|
||||
size={32}
|
||||
style={{marginRight: 10}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default class ChannelLoader extends PureComponent {
|
||||
static propTypes = {
|
||||
actions: PropTypes.shape({
|
||||
handleSelectChannel: PropTypes.func.isRequired,
|
||||
setChannelLoading: PropTypes.func.isRequired,
|
||||
}).isRequired,
|
||||
backgroundColor: PropTypes.string,
|
||||
channelIsLoading: PropTypes.bool.isRequired,
|
||||
style: CustomPropTypes.Style,
|
||||
|
|
@ -64,89 +66,36 @@ export default class ChannelLoader extends PureComponent {
|
|||
return Object.keys(state) ? state : null;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
EventEmitter.on('switch_channel', this.handleChannelSwitch);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
EventEmitter.off('switch_channel', this.handleChannelSwitch);
|
||||
}
|
||||
|
||||
startLoadingAnimation = () => {
|
||||
Animated.loop(
|
||||
Animated.sequence([
|
||||
Animated.timing(this.state.barsOpacity, {
|
||||
toValue: 1,
|
||||
duration: 750,
|
||||
easing: Easing.quad,
|
||||
useNativeDriver: true,
|
||||
}),
|
||||
Animated.timing(this.state.barsOpacity, {
|
||||
toValue: 0.6,
|
||||
duration: 750,
|
||||
easing: Easing.quad,
|
||||
useNativeDriver: true,
|
||||
}),
|
||||
]),
|
||||
).start();
|
||||
};
|
||||
|
||||
stopLoadingAnimation = () => {
|
||||
Animated.timing(
|
||||
this.state.barsOpacity,
|
||||
).stop();
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (prevProps.channelIsLoading === false && this.props.channelIsLoading === true) {
|
||||
this.startLoadingAnimation();
|
||||
} else if (prevProps.channelIsLoading === true && this.props.channelIsLoading === false) {
|
||||
this.stopLoadingAnimation();
|
||||
}
|
||||
|
||||
if (this.state.switch) {
|
||||
const {
|
||||
handleSelectChannel,
|
||||
setChannelLoading,
|
||||
} = this.props.actions;
|
||||
|
||||
const {channel} = this.state;
|
||||
|
||||
setTimeout(() => {
|
||||
handleSelectChannel(channel.id);
|
||||
setChannelLoading(false);
|
||||
}, 250);
|
||||
}
|
||||
}
|
||||
|
||||
buildSections({key, style, bg, color}) {
|
||||
return (
|
||||
<AnimatedView
|
||||
<View
|
||||
key={key}
|
||||
style={[style.section, {backgroundColor: bg}, {opacity: this.state.barsOpacity}]}
|
||||
style={[style.section, {backgroundColor: bg}]}
|
||||
>
|
||||
<ImageContent
|
||||
size={32}
|
||||
animate='fade'
|
||||
lineNumber={3}
|
||||
lineSpacing={5}
|
||||
firstLineWidth='80%'
|
||||
hasRadius={true}
|
||||
textSize={14}
|
||||
color={changeOpacity(color, 0.15)}
|
||||
/>
|
||||
</AnimatedView>
|
||||
<RNPlaceholder.Placeholder
|
||||
Animation={(props) => (
|
||||
<RNPlaceholder.Fade
|
||||
{...props}
|
||||
style={{backgroundColor: changeOpacity(bg, 0.9)}}
|
||||
/>
|
||||
)}
|
||||
Left={Media.bind(undefined, color)}
|
||||
styles={{left: {color: changeOpacity(color, 0.15)}}}
|
||||
>
|
||||
<RNPlaceholder.PlaceholderLine color={changeOpacity(color, 0.15)}/>
|
||||
<RNPlaceholder.PlaceholderLine
|
||||
color={changeOpacity(color, 0.15)}
|
||||
width={80}
|
||||
/>
|
||||
<RNPlaceholder.PlaceholderLine
|
||||
color={changeOpacity(color, 0.15)}
|
||||
width={60}
|
||||
/>
|
||||
</RNPlaceholder.Placeholder>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
handleChannelSwitch = (channel, currentChannelId) => {
|
||||
if (channel.id === currentChannelId) {
|
||||
this.props.actions.setChannelLoading(false);
|
||||
} else {
|
||||
this.setState({switch: true, channel});
|
||||
}
|
||||
};
|
||||
|
||||
handleLayout = (e) => {
|
||||
const {height} = e.nativeEvent.layout;
|
||||
const maxRows = calculateMaxRows(height);
|
||||
|
|
@ -192,7 +141,6 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
|||
},
|
||||
section: {
|
||||
backgroundColor: theme.centerChannelBg,
|
||||
flexDirection: 'row',
|
||||
flex: 1,
|
||||
paddingLeft: 12,
|
||||
paddingRight: 20,
|
||||
|
|
|
|||
|
|
@ -1,21 +1,16 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {bindActionCreators} from 'redux';
|
||||
import {connect} from 'react-redux';
|
||||
|
||||
import {getTheme} from '@mm-redux/selectors/entities/preferences';
|
||||
|
||||
import {handleSelectChannel, setChannelLoading} from 'app/actions/views/channel';
|
||||
import {isLandscape} from 'app/selectors/device';
|
||||
|
||||
import ChannelLoader from './channel_loader';
|
||||
|
||||
import {isLandscape} from 'app/selectors/device';
|
||||
|
||||
function mapStateToProps(state, ownProps) {
|
||||
const channelIsLoading = ownProps.hasOwnProperty('channelIsLoading') ?
|
||||
ownProps.channelIsLoading :
|
||||
state.views.channel.loading;
|
||||
const channelIsLoading = ownProps.hasOwnProperty('channelIsLoading') ? ownProps.channelIsLoading : state.views.channel.loading;
|
||||
|
||||
return {
|
||||
channelIsLoading,
|
||||
|
|
@ -24,13 +19,4 @@ function mapStateToProps(state, ownProps) {
|
|||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return {
|
||||
actions: bindActionCreators({
|
||||
handleSelectChannel,
|
||||
setChannelLoading,
|
||||
}, dispatch),
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(ChannelLoader);
|
||||
export default connect(mapStateToProps)(ChannelLoader);
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ import Preferences from '@mm-redux/constants/preferences';
|
|||
import UserListRow from './user_list_row';
|
||||
|
||||
jest.mock('react-intl');
|
||||
jest.mock('app/utils/theme', () => {
|
||||
const original = require.requireActual('app/utils/theme');
|
||||
jest.mock('@utils/theme', () => {
|
||||
const original = jest.requireActual('../../../utils/theme');
|
||||
return {
|
||||
...original,
|
||||
changeOpacity: jest.fn(),
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ export default class EmojiPicker extends PureComponent {
|
|||
return [];
|
||||
}
|
||||
|
||||
const results = fuse.search(searchTermLowerCase);
|
||||
const results = fuse.search(searchTermLowerCase).map((r) => r.refIndex);
|
||||
const sorter = (a, b) => compareEmojis(a, b, searchTerm);
|
||||
const data = results.map((index) => emojis[index]).sort(sorter);
|
||||
|
||||
|
|
|
|||
|
|
@ -2,21 +2,21 @@
|
|||
// See LICENSE.txt for license information.
|
||||
|
||||
import {connect} from 'react-redux';
|
||||
import {createSelector} from 'reselect';
|
||||
import {bindActionCreators} from 'redux';
|
||||
import {createSelector} from 'reselect';
|
||||
import Fuse from 'fuse.js';
|
||||
|
||||
import {incrementEmojiPickerPage} from '@actions/views/emoji';
|
||||
import {getCustomEmojis} from '@mm-redux/actions/emojis';
|
||||
import {getTheme} from '@mm-redux/selectors/entities/preferences';
|
||||
import {getCustomEmojisByName} from '@mm-redux/selectors/entities/emojis';
|
||||
import {getConfig} from '@mm-redux/selectors/entities/general';
|
||||
import {getCustomEmojis} from '@mm-redux/actions/emojis';
|
||||
|
||||
import {incrementEmojiPickerPage} from 'app/actions/views/emoji';
|
||||
import {getDimensions, isLandscape} from 'app/selectors/device';
|
||||
import {BuiltInEmojis, CategoryNames, Emojis, EmojiIndicesByAlias, EmojiIndicesByCategory} from 'app/utils/emojis';
|
||||
import {t} from 'app/utils/i18n';
|
||||
import {createIdsSelector} from '@mm-redux/utils/helpers';
|
||||
import {getDimensions, isLandscape} from '@selectors/device';
|
||||
import {BuiltInEmojis, CategoryNames, Emojis, EmojiIndicesByAlias, EmojiIndicesByCategory} from '@utils/emojis';
|
||||
import {t} from '@utils/i18n';
|
||||
|
||||
import EmojiPicker from './emoji_picker';
|
||||
import Fuse from 'fuse.js';
|
||||
|
||||
const categoryToI18n = {
|
||||
activity: {
|
||||
|
|
@ -128,7 +128,7 @@ const getEmojisBySection = createSelector(
|
|||
},
|
||||
);
|
||||
|
||||
const getEmojisByName = createSelector(
|
||||
const getEmojisByName = createIdsSelector(
|
||||
getCustomEmojisByName,
|
||||
(customEmojis) => {
|
||||
const emoticons = new Set();
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ import {shallow} from 'enzyme';
|
|||
import FileAttachment from './file_attachment.js';
|
||||
import Preferences from '@mm-redux/constants/preferences';
|
||||
|
||||
jest.mock('react-native-doc-viewer', () => ({
|
||||
openDoc: jest.fn(),
|
||||
jest.mock('react-native-file-viewer', () => ({
|
||||
open: jest.fn(),
|
||||
}));
|
||||
|
||||
describe('FileAttachment', () => {
|
||||
|
|
|
|||
|
|
@ -5,15 +5,13 @@ import React, {PureComponent} from 'react';
|
|||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
Alert,
|
||||
NativeModules,
|
||||
NativeEventEmitter,
|
||||
Platform,
|
||||
StatusBar,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import OpenFile from 'react-native-doc-viewer';
|
||||
import FileViewer from 'react-native-file-viewer';
|
||||
import RNFetchBlob from 'rn-fetch-blob';
|
||||
import {CircularProgress} from 'react-native-circular-progress';
|
||||
import {intlShape} from 'react-intl';
|
||||
|
|
@ -71,13 +69,10 @@ export default class FileAttachmentDocument extends PureComponent {
|
|||
|
||||
componentDidMount() {
|
||||
this.mounted = true;
|
||||
this.eventEmitter = new NativeEventEmitter(NativeModules.RNDocViewer);
|
||||
this.eventEmitter.addListener('DoneButtonEvent', this.onDonePreviewingFile);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.mounted = false;
|
||||
this.eventEmitter.removeListener();
|
||||
}
|
||||
|
||||
cancelDownload = () => {
|
||||
|
|
@ -217,7 +212,7 @@ export default class FileAttachmentDocument extends PureComponent {
|
|||
|
||||
onDonePreviewingFile = () => {
|
||||
if (this.mounted) {
|
||||
this.setState({preview: false});
|
||||
this.setState({progress: 0, downloading: false, preview: false});
|
||||
}
|
||||
this.setStatusBarColor();
|
||||
};
|
||||
|
|
@ -229,51 +224,41 @@ export default class FileAttachmentDocument extends PureComponent {
|
|||
setTimeout(() => {
|
||||
if (!this.state.didCancel && !this.state.preview && this.mounted) {
|
||||
const {data} = file;
|
||||
const prefix = Platform.OS === 'android' ? 'file:/' : '';
|
||||
const path = `${DOCUMENTS_PATH}/${data.id}-${file.caption}`;
|
||||
this.setState({preview: true});
|
||||
this.setStatusBarColor('dark-content');
|
||||
OpenFile.openDoc([{
|
||||
url: `${prefix}${path}`,
|
||||
fileNameOptional: file.caption,
|
||||
fileName: encodeURI(data.name.split('.').slice(0, -1).join('.')),
|
||||
fileType: data.extension,
|
||||
cache: false,
|
||||
}], (error) => {
|
||||
if (error) {
|
||||
const {intl} = this.context;
|
||||
Alert.alert(
|
||||
intl.formatMessage({
|
||||
id: 'mobile.document_preview.failed_title',
|
||||
defaultMessage: 'Open Document failed',
|
||||
}),
|
||||
intl.formatMessage({
|
||||
id: 'mobile.document_preview.failed_description',
|
||||
defaultMessage: 'An error occurred while opening the document. Please make sure you have a {fileType} viewer installed and try again.\n',
|
||||
}, {
|
||||
fileType: data.extension.toUpperCase(),
|
||||
}),
|
||||
[{
|
||||
text: intl.formatMessage({
|
||||
id: 'mobile.server_upgrade.button',
|
||||
defaultMessage: 'OK',
|
||||
}),
|
||||
}],
|
||||
);
|
||||
this.onDonePreviewingFile();
|
||||
RNFetchBlob.fs.unlink(path);
|
||||
}
|
||||
|
||||
FileViewer.open(path, {
|
||||
displayName: file.caption,
|
||||
onDismiss: this.onDonePreviewingFile,
|
||||
showOpenWithDialog: true,
|
||||
showAppsSuggestions: true,
|
||||
}).then(() => {
|
||||
if (this.mounted) {
|
||||
this.setState({downloading: false, progress: 0});
|
||||
}
|
||||
}).catch(() => {
|
||||
const {intl} = this.context;
|
||||
Alert.alert(
|
||||
intl.formatMessage({
|
||||
id: 'mobile.document_preview.failed_title',
|
||||
defaultMessage: 'Open Document failed',
|
||||
}),
|
||||
intl.formatMessage({
|
||||
id: 'mobile.document_preview.failed_description',
|
||||
defaultMessage: 'An error occurred while opening the document. Please make sure you have a {fileType} viewer installed and try again.\n',
|
||||
}, {
|
||||
fileType: data.extension.toUpperCase(),
|
||||
}),
|
||||
[{
|
||||
text: intl.formatMessage({
|
||||
id: 'mobile.server_upgrade.button',
|
||||
defaultMessage: 'OK',
|
||||
}),
|
||||
}],
|
||||
);
|
||||
this.onDonePreviewingFile();
|
||||
RNFetchBlob.fs.unlink(path);
|
||||
});
|
||||
|
||||
// Android does not trigger the event for DoneButtonEvent
|
||||
// so we'll wait 4 seconds before enabling the tap for open the preview again
|
||||
if (Platform.OS === 'android') {
|
||||
setTimeout(this.onDonePreviewingFile, 4000);
|
||||
}
|
||||
}
|
||||
}, delay);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ import {shallow} from 'enzyme';
|
|||
import FileAttachment from './file_attachment_list.js';
|
||||
import Preferences from '@mm-redux/constants/preferences';
|
||||
|
||||
jest.mock('react-native-doc-viewer', () => ({
|
||||
openDoc: jest.fn(),
|
||||
jest.mock('react-native-file-viewer', () => ({
|
||||
open: jest.fn(),
|
||||
}));
|
||||
|
||||
describe('FileAttachmentList', () => {
|
||||
|
|
|
|||
|
|
@ -3,10 +3,8 @@
|
|||
|
||||
import React, {PureComponent} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {intlShape} from 'react-intl';
|
||||
import {
|
||||
ActivityIndicator,
|
||||
Alert,
|
||||
Animated,
|
||||
AppState,
|
||||
Platform,
|
||||
|
|
@ -61,10 +59,6 @@ export default class NetworkIndicator extends PureComponent {
|
|||
isOnline: true,
|
||||
};
|
||||
|
||||
static contextTypes = {
|
||||
intl: intlShape.isRequired,
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
|
|
@ -129,8 +123,11 @@ export default class NetworkIndicator extends PureComponent {
|
|||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
const {closeWebSocket, stopPeriodicStatusUpdates} = this.props.actions;
|
||||
this.mounted = false;
|
||||
|
||||
closeWebSocket(false);
|
||||
stopPeriodicStatusUpdates();
|
||||
this.networkListener.removeEventListener();
|
||||
AppState.removeEventListener('change', this.handleAppStateChange);
|
||||
|
||||
|
|
@ -294,7 +291,6 @@ export default class NetworkIndicator extends PureComponent {
|
|||
};
|
||||
|
||||
initializeWebSocket = async () => {
|
||||
const {formatMessage} = this.context.intl;
|
||||
const {actions} = this.props;
|
||||
const {closeWebSocket, initWebSocket} = actions;
|
||||
const platform = Platform.OS;
|
||||
|
|
@ -305,21 +301,6 @@ export default class NetworkIndicator extends PureComponent {
|
|||
|
||||
initWebSocket({certificate, forceConnection: true}).catch(() => {
|
||||
// we should dispatch a failure and show the app as disconnected
|
||||
Alert.alert(
|
||||
formatMessage({id: 'mobile.authentication_error.title', defaultMessage: 'Authentication Error'}),
|
||||
formatMessage({
|
||||
id: 'mobile.authentication_error.message',
|
||||
defaultMessage: 'Mattermost has encountered an error. Please re-authenticate to start a new session.',
|
||||
}),
|
||||
[{
|
||||
text: formatMessage({
|
||||
id: 'navbar_dropdown.logout',
|
||||
defaultMessage: 'Logout',
|
||||
}),
|
||||
onPress: actions.logout,
|
||||
}],
|
||||
{cancelable: false},
|
||||
);
|
||||
closeWebSocket(true);
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import * as PostUtils from '@mm-redux/utils/post_utils';
|
|||
import {makeMapStateToProps} from './index.js';
|
||||
|
||||
jest.mock('@mm-redux/selectors/entities/channels', () => {
|
||||
const channels = require.requireActual('@mm-redux/selectors/entities/channels');
|
||||
const channels = jest.requireActual('../../mm-redux/selectors/entities/channels');
|
||||
|
||||
return {
|
||||
...channels,
|
||||
|
|
@ -18,7 +18,7 @@ jest.mock('@mm-redux/selectors/entities/channels', () => {
|
|||
});
|
||||
|
||||
jest.mock('@mm-redux/selectors/entities/preferences', () => {
|
||||
const preferences = require.requireActual('@mm-redux/selectors/entities/preferences');
|
||||
const preferences = jest.requireActual('../../mm-redux/selectors/entities/preferences');
|
||||
return {
|
||||
...preferences,
|
||||
getTheme: jest.fn(),
|
||||
|
|
@ -26,7 +26,7 @@ jest.mock('@mm-redux/selectors/entities/preferences', () => {
|
|||
});
|
||||
|
||||
jest.mock('@mm-redux/selectors/entities/general', () => {
|
||||
const general = require.requireActual('@mm-redux/selectors/entities/general');
|
||||
const general = jest.requireActual('../../mm-redux/selectors/entities/general');
|
||||
return {
|
||||
...general,
|
||||
getConfig: jest.fn(),
|
||||
|
|
@ -35,7 +35,7 @@ jest.mock('@mm-redux/selectors/entities/general', () => {
|
|||
});
|
||||
|
||||
jest.mock('@mm-redux/selectors/entities/users', () => {
|
||||
const users = require.requireActual('@mm-redux/selectors/entities/users');
|
||||
const users = jest.requireActual('../../mm-redux/selectors/entities/users');
|
||||
return {
|
||||
...users,
|
||||
getCurrentUserId: jest.fn(),
|
||||
|
|
@ -44,7 +44,7 @@ jest.mock('@mm-redux/selectors/entities/users', () => {
|
|||
});
|
||||
|
||||
jest.mock('@mm-redux/selectors/entities/teams', () => {
|
||||
const teams = require.requireActual('@mm-redux/selectors/entities/teams');
|
||||
const teams = jest.requireActual('../../mm-redux/selectors/entities/teams');
|
||||
return {
|
||||
...teams,
|
||||
getCurrentTeamId: jest.fn(),
|
||||
|
|
@ -52,7 +52,7 @@ jest.mock('@mm-redux/selectors/entities/teams', () => {
|
|||
});
|
||||
|
||||
jest.mock('@mm-redux/selectors/entities/emojis', () => {
|
||||
const emojis = require.requireActual('@mm-redux/selectors/entities/emojis');
|
||||
const emojis = jest.requireActual('../../mm-redux/selectors/entities/emojis');
|
||||
return {
|
||||
...emojis,
|
||||
getCustomEmojisByName: jest.fn(),
|
||||
|
|
@ -60,7 +60,7 @@ jest.mock('@mm-redux/selectors/entities/emojis', () => {
|
|||
});
|
||||
|
||||
jest.mock('@mm-redux/selectors/entities/posts', () => {
|
||||
const posts = require.requireActual('@mm-redux/selectors/entities/posts');
|
||||
const posts = jest.requireActual('../../mm-redux/selectors/entities/posts');
|
||||
return {
|
||||
...posts,
|
||||
makeGetReactionsForPost: () => jest.fn(),
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
/* eslint-disable no-import-assign */
|
||||
|
||||
import {Permissions} from '@mm-redux/constants';
|
||||
import * as channelSelectors from '@mm-redux/selectors/entities/channels';
|
||||
import * as userSelectors from '@mm-redux/selectors/entities/users';
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import DeviceInfo from 'react-native-device-info';
|
|||
import RNFetchBlobFS from 'rn-fetch-blob/fs';
|
||||
import keyMirror from '@mm-redux/utils/key_mirror';
|
||||
|
||||
const DeviceModel = DeviceInfo.getModel();
|
||||
|
||||
const deviceTypes = keyMirror({
|
||||
CONNECTION_CHANGED: null,
|
||||
DEVICE_DIMENSIONS_CHANGED: null,
|
||||
|
|
@ -17,7 +19,7 @@ export default {
|
|||
...deviceTypes,
|
||||
DOCUMENTS_PATH: `${RNFetchBlobFS.dirs.CacheDir}/Documents`,
|
||||
IMAGES_PATH: `${RNFetchBlobFS.dirs.CacheDir}/Images`,
|
||||
IS_IPHONE_WITH_INSETS: DeviceInfo.getModel().includes('iPhone X') || DeviceInfo.getModel().includes('iPhone 11'),
|
||||
IS_IPHONE_WITH_INSETS: DeviceModel.includes('iPhone X') || DeviceModel.includes('iPhone 11'),
|
||||
IS_TABLET: DeviceInfo.isTablet(),
|
||||
VIDEOS_PATH: `${RNFetchBlobFS.dirs.CacheDir}/Videos`,
|
||||
PERMANENT_SIDEBAR_SETTINGS: '@PERMANENT_SIDEBAR_SETTINGS',
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@
|
|||
|
||||
import {Alert, AppState, Dimensions, Linking, NativeModules, Platform} from 'react-native';
|
||||
import AsyncStorage from '@react-native-community/async-storage';
|
||||
import CookieManager from 'react-native-cookies';
|
||||
import CookieManager from '@react-native-community/cookies';
|
||||
import DeviceInfo from 'react-native-device-info';
|
||||
import {getLocales} from 'react-native-localize';
|
||||
import RNFetchBlob from 'rn-fetch-blob';
|
||||
import semver from 'semver/preload';
|
||||
|
||||
|
|
@ -15,7 +16,7 @@ import {Client4} from '@mm-redux/client';
|
|||
import {General} from '@mm-redux/constants';
|
||||
import {getConfig} from '@mm-redux/selectors/entities/general';
|
||||
import {getCurrentChannelId} from '@mm-redux/selectors/entities/channels';
|
||||
import {getCurrentUserId, getUser} from '@mm-redux/selectors/entities/users';
|
||||
import {getCurrentUser, getUser} from '@mm-redux/selectors/entities/users';
|
||||
import {isTimezoneEnabled} from '@mm-redux/selectors/entities/timezone';
|
||||
import EventEmitter from '@mm-redux/utils/event_emitter';
|
||||
|
||||
|
|
@ -27,16 +28,16 @@ import {loadMe, logout} from '@actions/views/user';
|
|||
import LocalConfig from '@assets/config';
|
||||
import {NavigationTypes, ViewTypes} from '@constants';
|
||||
import {getTranslations, resetMomentLocale} from '@i18n';
|
||||
import PushNotifications from 'app/push_notifications';
|
||||
import {getCurrentLocale} from '@selectors/i18n';
|
||||
import initialState from '@store/initial_state';
|
||||
import Store from '@store/store';
|
||||
import {t} from '@utils/i18n';
|
||||
import {deleteFileCache} from '@utils/file';
|
||||
import {getDeviceTimezoneAsync} from '@utils/timezone';
|
||||
import {getDeviceTimezone} from '@utils/timezone';
|
||||
|
||||
import mattermostBucket from 'app/mattermost_bucket';
|
||||
import mattermostManaged from 'app/mattermost_managed';
|
||||
import PushNotifications from 'app/push_notifications';
|
||||
|
||||
import {getAppCredentials, removeAppCredentials} from './credentials';
|
||||
import emmProvider from './emm_provider';
|
||||
|
|
@ -162,7 +163,6 @@ class GlobalEventHandler {
|
|||
onLogout = async () => {
|
||||
Store.redux.dispatch(closeWebSocket(false));
|
||||
Store.redux.dispatch(setServerVersion(''));
|
||||
await this.resetState();
|
||||
|
||||
if (analytics) {
|
||||
await analytics.reset();
|
||||
|
|
@ -170,6 +170,7 @@ class GlobalEventHandler {
|
|||
|
||||
removeAppCredentials();
|
||||
deleteFileCache();
|
||||
await this.resetState();
|
||||
resetMomentLocale();
|
||||
|
||||
// TODO: Handle when multi-server support is added
|
||||
|
|
@ -245,28 +246,30 @@ class GlobalEventHandler {
|
|||
}
|
||||
};
|
||||
|
||||
onServerVersionChanged = (serverVersion) => {
|
||||
const {dispatch, getState} = Store.redux;
|
||||
const state = getState();
|
||||
const match = serverVersion && serverVersion.match(/^[0-9]*.[0-9]*.[0-9]*(-[a-zA-Z0-9.-]*)?/g);
|
||||
const version = match && match[0];
|
||||
const locale = getCurrentLocale(state);
|
||||
const translations = getTranslations(locale);
|
||||
onServerVersionChanged = async (serverVersion) => {
|
||||
if (Store?.redux?.dispatch) {
|
||||
const {dispatch, getState} = Store.redux;
|
||||
const state = getState();
|
||||
const match = serverVersion && serverVersion.match(/^[0-9]*.[0-9]*.[0-9]*(-[a-zA-Z0-9.-]*)?/g);
|
||||
const version = match && match[0];
|
||||
const locale = getCurrentLocale(state);
|
||||
const translations = getTranslations(locale);
|
||||
|
||||
if (serverVersion) {
|
||||
if (semver.valid(version) && semver.lt(version, LocalConfig.MinServerVersion)) {
|
||||
Alert.alert(
|
||||
translations[t('mobile.server_upgrade.title')],
|
||||
translations[t('mobile.server_upgrade.description')],
|
||||
[{
|
||||
text: translations[t('mobile.server_upgrade.button')],
|
||||
onPress: this.serverUpgradeNeeded,
|
||||
}],
|
||||
{cancelable: false},
|
||||
);
|
||||
} else if (state.entities.users && state.entities.users.currentUserId) {
|
||||
dispatch(setServerVersion(serverVersion));
|
||||
dispatch(loadConfigAndLicense());
|
||||
if (serverVersion) {
|
||||
if (semver.valid(version) && semver.lt(version, LocalConfig.MinServerVersion)) {
|
||||
Alert.alert(
|
||||
translations[t('mobile.server_upgrade.title')],
|
||||
translations[t('mobile.server_upgrade.description')],
|
||||
[{
|
||||
text: translations[t('mobile.server_upgrade.button')],
|
||||
onPress: this.serverUpgradeNeeded,
|
||||
}],
|
||||
{cancelable: false},
|
||||
);
|
||||
} else if (state.entities.users && state.entities.users.currentUserId) {
|
||||
dispatch(setServerVersion(serverVersion));
|
||||
dispatch(loadConfigAndLicense());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -299,7 +302,7 @@ class GlobalEventHandler {
|
|||
},
|
||||
views: {
|
||||
i18n: {
|
||||
locale: DeviceInfo.getDeviceLocale().split('-')[0],
|
||||
locale: getLocales()[0].languageCode,
|
||||
},
|
||||
root: {
|
||||
hydrationComplete: true,
|
||||
|
|
@ -368,12 +371,27 @@ class GlobalEventHandler {
|
|||
setUserTimezone = async () => {
|
||||
const {dispatch, getState} = Store.redux;
|
||||
const state = getState();
|
||||
const currentUserId = getCurrentUserId(state);
|
||||
const currentUser = getCurrentUser(state);
|
||||
|
||||
const enableTimezone = isTimezoneEnabled(state);
|
||||
if (enableTimezone && currentUserId) {
|
||||
const timezone = await getDeviceTimezoneAsync();
|
||||
dispatch(autoUpdateTimezone(timezone));
|
||||
if (enableTimezone && currentUser.id) {
|
||||
const timezone = getDeviceTimezone();
|
||||
const {
|
||||
automaticTimezone,
|
||||
manualTimezone,
|
||||
useAutomaticTimezone,
|
||||
} = currentUser.timezone;
|
||||
let updateTimeZone = false;
|
||||
|
||||
if (useAutomaticTimezone) {
|
||||
updateTimeZone = timezone !== automaticTimezone;
|
||||
} else {
|
||||
updateTimeZone = timezone !== manualTimezone;
|
||||
}
|
||||
|
||||
if (updateTimeZone) {
|
||||
dispatch(autoUpdateTimezone(timezone));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1198,7 +1198,7 @@ export function updateChannelMemberRoles(channelId: string, userId: string, role
|
|||
}
|
||||
|
||||
export function updateChannelHeader(channelId: string, header: string): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
return async (dispatch: DispatchFunc) => {
|
||||
Client4.trackEvent('action', 'action_channels_update_header', {channel_id: channelId});
|
||||
|
||||
dispatch({
|
||||
|
|
@ -1214,7 +1214,7 @@ export function updateChannelHeader(channelId: string, header: string): ActionFu
|
|||
}
|
||||
|
||||
export function updateChannelPurpose(channelId: string, purpose: string): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
return async (dispatch: DispatchFunc) => {
|
||||
Client4.trackEvent('action', 'action_channels_update_purpose', {channel_id: channelId});
|
||||
|
||||
dispatch({
|
||||
|
|
|
|||
|
|
@ -3,11 +3,10 @@
|
|||
import {Client4} from '@mm-redux/client';
|
||||
import {FileTypes} from '@mm-redux/action_types';
|
||||
|
||||
import {Action, batchActions, DispatchFunc, GetStateFunc, ActionFunc} from '@mm-redux/types/actions';
|
||||
import {DispatchFunc, GetStateFunc, ActionFunc} from '@mm-redux/types/actions';
|
||||
|
||||
import {logError} from './errors';
|
||||
import {bindClientFunc, forceLogoutIfNecessary} from './helpers';
|
||||
import {FileUploadResponse} from '@mm-redux/types/files';
|
||||
|
||||
export function getFilesForPost(postId: string): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ export function getPing(): ActionFunc {
|
|||
}
|
||||
|
||||
export function resetPing(): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
return async (dispatch: DispatchFunc) => {
|
||||
dispatch({type: GeneralTypes.PING_RESET, data: {}});
|
||||
|
||||
return {data: true};
|
||||
|
|
@ -115,7 +115,7 @@ export function logClientError(message: string, level: logLevel = 'ERROR') {
|
|||
}
|
||||
|
||||
export function setAppState(state: GeneralState['appState']): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
return async (dispatch: DispatchFunc) => {
|
||||
dispatch({type: GeneralTypes.RECEIVED_APP_STATE, data: state});
|
||||
|
||||
return {data: true};
|
||||
|
|
@ -123,7 +123,7 @@ export function setAppState(state: GeneralState['appState']): ActionFunc {
|
|||
}
|
||||
|
||||
export function setDeviceToken(token: GeneralState['deviceToken']): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
return async (dispatch: DispatchFunc) => {
|
||||
dispatch({type: GeneralTypes.RECEIVED_APP_DEVICE_TOKEN, data: token});
|
||||
|
||||
return {data: true};
|
||||
|
|
@ -131,7 +131,7 @@ export function setDeviceToken(token: GeneralState['deviceToken']): ActionFunc {
|
|||
}
|
||||
|
||||
export function setServerVersion(serverVersion: string): ActionFunc {
|
||||
return async (dispatch, getState: GetStateFunc) => {
|
||||
return async (dispatch) => {
|
||||
dispatch({type: GeneralTypes.RECEIVED_SERVER_VERSION, data: serverVersion});
|
||||
dispatch(loadRolesIfNeeded([]));
|
||||
|
||||
|
|
|
|||
|
|
@ -414,7 +414,7 @@ export function cacheGifs(gifs: any) {
|
|||
}
|
||||
|
||||
export function cacheGifsRequest(gifs: any) {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
return async (dispatch: DispatchFunc) => {
|
||||
dispatch(cacheRequest());
|
||||
dispatch(cacheGifs(gifs));
|
||||
return {data: true};
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ export function forceLogoutIfNecessary(err: Client4Error, dispatch: DispatchFunc
|
|||
}
|
||||
}
|
||||
|
||||
function dispatcher(type: ActionType, data: any, dispatch: DispatchFunc, getState: GetStateFunc) {
|
||||
function dispatcher(type: ActionType, data: any, dispatch: DispatchFunc) {
|
||||
if (type.indexOf('SUCCESS') === -1) { // we don't want to pass the data for the request types
|
||||
dispatch(requestSuccess(type, data));
|
||||
} else {
|
||||
|
|
@ -93,10 +93,10 @@ export function bindClientFunc({
|
|||
|
||||
if (Array.isArray(onSuccess)) {
|
||||
onSuccess.forEach((s) => {
|
||||
dispatcher(s, data, dispatch, getState);
|
||||
dispatcher(s, data, dispatch);
|
||||
});
|
||||
} else if (onSuccess) {
|
||||
dispatcher(onSuccess, data, dispatch, getState);
|
||||
dispatcher(onSuccess, data, dispatch);
|
||||
}
|
||||
|
||||
return {data};
|
||||
|
|
|
|||
|
|
@ -207,8 +207,8 @@ export function createPost(post: Post, files: any[] = []) {
|
|||
actions.push({
|
||||
type: PostTypes.RECEIVED_NEW_POST,
|
||||
data: {
|
||||
id: pendingPostId,
|
||||
...newPost,
|
||||
id: pendingPostId,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -305,8 +305,8 @@ export function createPostImmediately(post: Post, files: any[] = []) {
|
|||
}
|
||||
|
||||
dispatch(receivedNewPost({
|
||||
id: pendingPostId,
|
||||
...newPost,
|
||||
id: pendingPostId,
|
||||
}));
|
||||
|
||||
try {
|
||||
|
|
@ -316,7 +316,7 @@ export function createPostImmediately(post: Post, files: any[] = []) {
|
|||
forceLogoutIfNecessary(error, dispatch, getState);
|
||||
dispatch(batchActions([
|
||||
{type: PostTypes.CREATE_POST_FAILURE, error},
|
||||
removePost({id: pendingPostId, ...newPost}) as any,
|
||||
removePost({...newPost, id: pendingPostId}) as any,
|
||||
logError(error),
|
||||
]));
|
||||
return {error};
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
import {Client4} from '@mm-redux/client';
|
||||
import {RoleTypes} from '@mm-redux/action_types';
|
||||
import {getRoles} from '@mm-redux/selectors/entities/roles_helpers';
|
||||
import {hasNewPermissions} from '@mm-redux/selectors/entities/general';
|
||||
|
||||
import {DispatchFunc, GetStateFunc, ActionFunc} from '@mm-redux/types/actions';
|
||||
import {Role} from '@mm-redux/types/roles';
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import {General} from '../constants';
|
|||
|
||||
import {Scheme, SchemeScope, SchemePatch} from '@mm-redux/types/schemes';
|
||||
|
||||
import {ActionFunc, batchActions, DispatchFunc, GetStateFunc} from '@mm-redux/types/actions';
|
||||
import {ActionFunc, DispatchFunc, GetStateFunc} from '@mm-redux/types/actions';
|
||||
|
||||
import {bindClientFunc, forceLogoutIfNecessary} from './helpers';
|
||||
import {logError} from './errors';
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ async function getProfilesAndStatusesForMembers(userIds: string[], dispatch: Dis
|
|||
}
|
||||
|
||||
export function selectTeam(team: Team | string): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
return async (dispatch: DispatchFunc) => {
|
||||
const teamId = (typeof team === 'string') ? team : team.id;
|
||||
dispatch({
|
||||
type: TeamTypes.SELECT_TEAM,
|
||||
|
|
|
|||
|
|
@ -917,14 +917,14 @@ describe('Actions.Users', () => {
|
|||
post('/users').
|
||||
reply(200, TestHelper.fakeUserWithId());
|
||||
|
||||
const {data: user} = await Actions.createUser(TestHelper.fakeUser())(store.dispatch, store.getState);
|
||||
const {data: user} = await store.dispatch(Actions.createUser(TestHelper.fakeUser()));
|
||||
|
||||
const beforeTime = new Date().getTime();
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
put(`/users/${user.id}/active`).
|
||||
reply(200, OK_RESPONSE);
|
||||
await Actions.updateUserActive(user.id, false)(store.dispatch, store.getState);
|
||||
await store.dispatch(Actions.updateUserActive(user.id, false));
|
||||
|
||||
const {profiles} = store.getState().entities.users;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import {combineReducers} from 'redux';
|
|||
|
||||
import {CategoryTypes} from '../../constants/channel_categories';
|
||||
|
||||
import {ChannelCategoryTypes, TeamTypes} from '@mm-redux/action_types';
|
||||
import {TeamTypes} from '@mm-redux/action_types';
|
||||
|
||||
import {GenericAction} from '@mm-redux/types/actions';
|
||||
import {ChannelCategory} from '@mm-redux/types/channel_categories';
|
||||
|
|
|
|||
|
|
@ -4,8 +4,6 @@ import {combineReducers} from 'redux';
|
|||
import {GroupTypes} from '@mm-redux/action_types';
|
||||
import {GroupChannel, GroupSyncables, GroupTeam, Group} from '@mm-redux/types/groups';
|
||||
import {GenericAction} from '@mm-redux/types/actions';
|
||||
import {Team, TeamMembership} from '@mm-redux/types/teams';
|
||||
import {ChannelMembership} from '@mm-redux/types/channels';
|
||||
import {Dictionary} from '@mm-redux/types/utilities';
|
||||
|
||||
function syncables(state: Dictionary<GroupSyncables> = {}, action: GenericAction) {
|
||||
|
|
|
|||
|
|
@ -1170,7 +1170,7 @@ export function expandedURLs(state: Dictionary<string> = {}, action: GenericActi
|
|||
}
|
||||
}
|
||||
|
||||
export default function(state: Partial<PostsState> = {}, action: GenericAction) {
|
||||
export default function reducer(state: Partial<PostsState> = {}, action: GenericAction) {
|
||||
const nextPosts = handlePosts(state.posts, action);
|
||||
const nextPostsInChannel = postsInChannel(state.postsInChannel, action, state.posts!, nextPosts);
|
||||
|
||||
|
|
|
|||
|
|
@ -411,7 +411,7 @@ function updateTeamMemberSchemeRoles(state: RelationOneToOne<Team, RelationOneTo
|
|||
}
|
||||
|
||||
function updateMyTeamMemberSchemeRoles(state: RelationOneToOne<Team, TeamMembership>, action: GenericAction) {
|
||||
const {teamId, userId, isSchemeUser, isSchemeAdmin} = action.data;
|
||||
const {teamId, isSchemeUser, isSchemeAdmin} = action.data;
|
||||
const member = state[teamId];
|
||||
if (member) {
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {GeneralTypes, UserTypes} from '@mm-redux/action_types';
|
||||
import {GeneralTypes} from '@mm-redux/action_types';
|
||||
import {GenericAction} from '@mm-redux/types/actions';
|
||||
|
||||
function getInitialState() {
|
||||
|
|
@ -12,7 +12,7 @@ function getInitialState() {
|
|||
};
|
||||
}
|
||||
|
||||
export default function(state = getInitialState(), action: GenericAction) {
|
||||
export default function reducer(state = getInitialState(), action: GenericAction) {
|
||||
if (!state.connected && action.type === GeneralTypes.WEBSOCKET_SUCCESS) {
|
||||
return {
|
||||
...state,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import {getCurrentTeamId} from '@mm-redux/selectors/entities/teams';
|
|||
import {createShallowSelector} from '@mm-redux/utils/helpers';
|
||||
import {getPreferenceKey} from '@mm-redux/utils/preference_utils';
|
||||
import {GlobalState} from '@mm-redux/types/store';
|
||||
import {PreferencesType, PreferenceType} from '@mm-redux/types/preferences';
|
||||
import {PreferenceType} from '@mm-redux/types/preferences';
|
||||
|
||||
export function getMyPreferences(state: GlobalState) {
|
||||
return state.entities.preferences.myPreferences;
|
||||
|
|
|
|||
|
|
@ -4,9 +4,7 @@
|
|||
import {CustomEmoji} from './emojis';
|
||||
import {FileInfo} from './files';
|
||||
import {Reaction} from './reactions';
|
||||
import {Channel} from './channels';
|
||||
import {
|
||||
$ID,
|
||||
RelationOneToOne,
|
||||
RelationOneToMany,
|
||||
IDMappedObjects,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ let activeKey: string|null = null;
|
|||
let activeSecret: string | null = null;
|
||||
|
||||
let instance: any = null;
|
||||
export default function(key: string, secret: string): any {
|
||||
export default function gifycat(key: string, secret: string): any {
|
||||
if (instance && activeKey === key && activeSecret === secret) {
|
||||
return instance;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
/* eslint-disable no-import-assign */
|
||||
|
||||
import NotificationsIOS from 'react-native-notifications';
|
||||
|
||||
import * as ViewSelectors from '@selectors/views';
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@
|
|||
// See LICENSE.txt for license information.
|
||||
|
||||
import {combineReducers} from 'redux';
|
||||
import DeviceInfo from 'react-native-device-info';
|
||||
import {getLocales} from 'react-native-localize';
|
||||
|
||||
import {UserTypes} from '@mm-redux/action_types';
|
||||
|
||||
const defaultLocale = DeviceInfo.getDeviceLocale().split('-')[0];
|
||||
const defaultLocale = getLocales()[0].languageCode;
|
||||
|
||||
function locale(state = defaultLocale, action) {
|
||||
switch (action.type) {
|
||||
|
|
|
|||
|
|
@ -27,6 +27,10 @@ describe('ChannelAddMembers', () => {
|
|||
isLandscape: false,
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
jest.useFakeTimers();
|
||||
});
|
||||
|
||||
test('should render without error and call functions on mount', () => {
|
||||
const setButtons = jest.spyOn(NavigationActions, 'setButtons');
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ jest.mock('@assets/images/channel_info/pin.png', () => {
|
|||
});
|
||||
|
||||
jest.mock('@utils/theme', () => {
|
||||
const original = require.requireActual('app/utils/theme');
|
||||
const original = jest.requireActual('../../utils/theme');
|
||||
return {
|
||||
...original,
|
||||
changeOpacity: jest.fn(),
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import {General} from '@mm-redux/constants';
|
|||
|
||||
import ChannelInfoHeader from './channel_info_header.js';
|
||||
|
||||
jest.mock('app/utils/theme', () => {
|
||||
const original = require.requireActual('app/utils/theme');
|
||||
jest.mock('@utils/theme', () => {
|
||||
const original = jest.requireActual('../../utils/theme');
|
||||
return {
|
||||
...original,
|
||||
changeOpacity: jest.fn(),
|
||||
|
|
|
|||
|
|
@ -24,6 +24,10 @@ describe('ChannelMembers', () => {
|
|||
isLandscape: false,
|
||||
};
|
||||
|
||||
beforeAll(() => {
|
||||
jest.useFakeTimers();
|
||||
});
|
||||
|
||||
test('should match snapshot', () => {
|
||||
const wrapper = shallowWithIntl(
|
||||
<ChannelMembers {...baseProps}/>,
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import Preferences from '@mm-redux/constants/preferences';
|
|||
import EditProfile from './edit_profile.js';
|
||||
|
||||
jest.mock('react-intl');
|
||||
jest.mock('app/utils/theme', () => {
|
||||
const original = require.requireActual('app/utils/theme');
|
||||
jest.mock('@utils/theme', () => {
|
||||
const original = jest.requireActual('../../utils/theme');
|
||||
return {
|
||||
...original,
|
||||
changeOpacity: jest.fn(),
|
||||
|
|
|
|||
|
|
@ -17,17 +17,9 @@ import ImagePreview from './image_preview';
|
|||
|
||||
jest.useFakeTimers();
|
||||
jest.mock('react-intl');
|
||||
jest.mock('react-native-doc-viewer', () => {
|
||||
return {
|
||||
OpenFile: jest.fn(),
|
||||
};
|
||||
});
|
||||
|
||||
// jest.mock('react-native-permissions', () => {
|
||||
// return {
|
||||
// check: jest.fn(),
|
||||
// };
|
||||
// });
|
||||
jest.mock('react-native-file-viewer', () => ({
|
||||
open: jest.fn(),
|
||||
}));
|
||||
|
||||
describe('ImagePreview', () => {
|
||||
const baseProps = {
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ import {shallowWithIntl} from 'test/intl-test-helper';
|
|||
|
||||
import LongPost from './long_post';
|
||||
|
||||
jest.mock('react-native-doc-viewer', () => ({
|
||||
openDoc: jest.fn(),
|
||||
jest.mock('react-native-file-viewer', () => ({
|
||||
open: jest.fn(),
|
||||
}));
|
||||
|
||||
describe('LongPost', () => {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import {makeMapStateToProps} from './index';
|
||||
|
||||
/* eslint-disable no-import-assign */
|
||||
|
||||
import {Permissions} from '@mm-redux/constants';
|
||||
import * as channelSelectors from '@mm-redux/selectors/entities/channels';
|
||||
|
|
@ -13,6 +14,8 @@ import * as deviceSelectors from 'app/selectors/device';
|
|||
import * as preferencesSelectors from '@mm-redux/selectors/entities/preferences';
|
||||
import {isMinimumServerVersion} from '@mm-redux/utils/helpers';
|
||||
|
||||
import {makeMapStateToProps} from './index';
|
||||
|
||||
jest.mock('@mm-redux/utils/post_utils');
|
||||
|
||||
channelSelectors.getChannel = jest.fn();
|
||||
|
|
|
|||
|
|
@ -211,6 +211,7 @@ export default class SelectServer extends PureComponent {
|
|||
return;
|
||||
}
|
||||
|
||||
await globalEventHandler.resetState();
|
||||
if (LocalConfig.ExperimentalClientSideCertEnable && Platform.OS === 'ios') {
|
||||
RNFetchBlob.cba.selectCertificate((certificate) => {
|
||||
if (certificate) {
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ import {RequestStatus} from '@mm-redux/constants';
|
|||
|
||||
import SelectTeam from './select_team.js';
|
||||
|
||||
jest.mock('app/utils/theme', () => {
|
||||
const original = require.requireActual('app/utils/theme');
|
||||
jest.mock('@utils/theme', () => {
|
||||
const original = jest.requireActual('../../utils/theme');
|
||||
return {
|
||||
...original,
|
||||
changeOpacity: jest.fn(),
|
||||
|
|
|
|||
|
|
@ -8,22 +8,6 @@ import Preferences from '@mm-redux/constants/preferences';
|
|||
|
||||
import SelectorScreen from './selector_screen.js';
|
||||
|
||||
jest.mock('rn-fetch-blob', () => ({
|
||||
fs: {
|
||||
dirs: {
|
||||
DocumentDir: () => jest.fn(),
|
||||
CacheDir: () => jest.fn(),
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
jest.mock('rn-fetch-blob/fs', () => ({
|
||||
dirs: {
|
||||
DocumentDir: () => jest.fn(),
|
||||
CacheDir: () => jest.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
const user1 = {id: 'id', username: 'username'};
|
||||
const user2 = {id: 'id2', username: 'username2'};
|
||||
|
||||
|
|
@ -79,6 +63,10 @@ describe('SelectorScreen', () => {
|
|||
isLandscape: false,
|
||||
};
|
||||
|
||||
beforeAll(() => {
|
||||
jest.useFakeTimers();
|
||||
});
|
||||
|
||||
test('should match snapshot for explicit options', async () => {
|
||||
const wrapper = shallow(
|
||||
<SelectorScreen {...baseProps}/>,
|
||||
|
|
|
|||
|
|
@ -6,12 +6,12 @@ import {shallow} from 'enzyme';
|
|||
|
||||
import Preferences from '@mm-redux/constants/preferences';
|
||||
|
||||
import SectionItem from 'app/screens/settings/section_item';
|
||||
import SectionItem from '@screens/settings/section_item';
|
||||
|
||||
import NotificationSettingsEmailIos from './notification_settings_email.ios.js';
|
||||
|
||||
jest.mock('app/utils/theme', () => {
|
||||
const original = require.requireActual('app/utils/theme');
|
||||
jest.mock('@utils/theme', () => {
|
||||
const original = jest.requireActual('../../../utils/theme');
|
||||
return {
|
||||
...original,
|
||||
changeOpacity: jest.fn(),
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import StatusBar from 'app/components/status_bar';
|
|||
import Section from 'app/screens/settings/section';
|
||||
import SectionItem from 'app/screens/settings/section_item';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
|
||||
import {getDeviceTimezoneAsync} from 'app/utils/timezone';
|
||||
import {getDeviceTimezone} from 'app/utils/timezone';
|
||||
import {goToScreen} from 'app/actions/navigation';
|
||||
|
||||
export default class Timezone extends PureComponent {
|
||||
|
|
@ -61,13 +61,13 @@ export default class Timezone extends PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
updateAutomaticTimezone = async (useAutomaticTimezone) => {
|
||||
updateAutomaticTimezone = (useAutomaticTimezone) => {
|
||||
const {userTimezone: {manualTimezone}} = this.props;
|
||||
let automaticTimezone = '';
|
||||
|
||||
this.setState({useAutomaticTimezone});
|
||||
if (useAutomaticTimezone) {
|
||||
automaticTimezone = await getDeviceTimezoneAsync();
|
||||
automaticTimezone = getDeviceTimezone();
|
||||
this.submitUser({
|
||||
useAutomaticTimezone,
|
||||
automaticTimezone,
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import {
|
|||
Platform,
|
||||
} from 'react-native';
|
||||
import {WebView} from 'react-native-webview';
|
||||
import CookieManager from 'react-native-cookies';
|
||||
import CookieManager from '@react-native-community/cookies';
|
||||
import urlParse from 'url-parse';
|
||||
|
||||
import {Client4} from '@mm-redux/client';
|
||||
|
|
@ -27,7 +27,7 @@ const HEADERS = {
|
|||
'X-Mobile-App': 'mattermost',
|
||||
};
|
||||
|
||||
const postMessageJS = "window.postMessage(document.body.innerText, '*');";
|
||||
const postMessageJS = "window.ReactNativeWebView.postMessage(document.body.innerText, '*');";
|
||||
|
||||
// Used to make sure that OneLogin forms scale appropriately on both platforms.
|
||||
const oneLoginFormScalingJS = `
|
||||
|
|
@ -152,7 +152,8 @@ class SSO extends PureComponent {
|
|||
const url = event.nativeEvent.url;
|
||||
if (url.includes(this.completedUrl)) {
|
||||
CookieManager.get(this.props.serverUrl, this.useWebkit).then((res) => {
|
||||
const token = res.MMAUTHTOKEN;
|
||||
const mmtoken = res.MMAUTHTOKEN;
|
||||
const token = typeof mmtoken === 'object' ? mmtoken.value : mmtoken;
|
||||
|
||||
if (token) {
|
||||
this.setState({renderWebView: false});
|
||||
|
|
@ -213,7 +214,7 @@ class SSO extends PureComponent {
|
|||
<WebView
|
||||
ref={this.webViewRef}
|
||||
source={{uri: this.loginUrl, headers: HEADERS}}
|
||||
javaScriptEnabledAndroid={true}
|
||||
javaScriptEnabled={true}
|
||||
automaticallyAdjustContentInsets={false}
|
||||
startInLoadingState={true}
|
||||
onNavigationStateChange={this.onNavigationStateChange}
|
||||
|
|
@ -221,7 +222,7 @@ class SSO extends PureComponent {
|
|||
injectedJavaScript={jsCode}
|
||||
onLoadEnd={this.onLoadEnd}
|
||||
onMessage={messagingEnabled ? this.onMessage : null}
|
||||
useSharedProcessPool={true}
|
||||
sharedCookiesEnabled={Platform.OS === 'android'}
|
||||
cacheEnabled={false}
|
||||
/>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -6,14 +6,14 @@ import {shallow} from 'enzyme';
|
|||
|
||||
import Preferences from '@mm-redux/constants/preferences';
|
||||
|
||||
import * as NavigationActions from 'app/actions/navigation';
|
||||
import * as NavigationActions from '@actions/navigation';
|
||||
|
||||
import TermsOfService from './terms_of_service.js';
|
||||
|
||||
jest.mock('react-intl');
|
||||
|
||||
jest.mock('app/utils/theme', () => {
|
||||
const original = require.requireActual('app/utils/theme');
|
||||
jest.mock('@utils/theme', () => {
|
||||
const original = jest.requireActual('../../utils/theme');
|
||||
return {
|
||||
...original,
|
||||
changeOpacity: jest.fn(),
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ import UserProfile from './user_profile.js';
|
|||
import {BotTag, GuestTag} from 'app/components/tag';
|
||||
|
||||
jest.mock('react-intl');
|
||||
jest.mock('app/utils/theme', () => {
|
||||
const original = require.requireActual('app/utils/theme');
|
||||
jest.mock('@utils/theme', () => {
|
||||
const original = jest.requireActual('../../utils/theme');
|
||||
return {
|
||||
...original,
|
||||
changeOpacity: jest.fn(),
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import DeviceInfo from 'react-native-device-info';
|
||||
import {getLocales} from 'react-native-localize';
|
||||
|
||||
import {DEFAULT_LOCALE} from '@mm-redux/constants/general';
|
||||
import {getCurrentUserLocale} from '@mm-redux/selectors/entities/i18n';
|
||||
|
||||
// Not a proper selector since the device locale isn't in the redux store
|
||||
export function getCurrentLocale(state) {
|
||||
const deviceLocale = DeviceInfo.getDeviceLocale().split('-')[0];
|
||||
const deviceLocale = getLocales()[0].languageCode;
|
||||
const defaultLocale = deviceLocale || DEFAULT_LOCALE;
|
||||
|
||||
return getCurrentUserLocale(state, defaultLocale);
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ class Telemetry {
|
|||
});
|
||||
}
|
||||
|
||||
save() {
|
||||
async save() {
|
||||
if (!this.canSendTelemetry()) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
import {Dimensions} from 'react-native';
|
||||
import DeviceInfo from 'react-native-device-info';
|
||||
import * as RNLocalize from 'react-native-localize';
|
||||
|
||||
import LocalConfig from '@assets/config';
|
||||
|
||||
|
|
@ -67,28 +68,28 @@ export function setTraceRecord({
|
|||
};
|
||||
}
|
||||
|
||||
export function getDeviceInfo() {
|
||||
export async function getDeviceInfo() {
|
||||
const {height, width} = Dimensions.get('window');
|
||||
|
||||
return {
|
||||
api_level: DeviceInfo.getAPILevel(),
|
||||
api_level: await DeviceInfo.getAPILevel(),
|
||||
build_number: DeviceInfo.getBuildNumber(),
|
||||
bundle_id: DeviceInfo.getBundleId(),
|
||||
brand: DeviceInfo.getBrand(),
|
||||
country: DeviceInfo.getDeviceCountry(),
|
||||
country: RNLocalize.getCountry(),
|
||||
device_id: DeviceInfo.getDeviceId(),
|
||||
device_locale: DeviceInfo.getDeviceLocale().split('-')[0],
|
||||
device_locale: RNLocalize.getLocales()[0].languageCode,
|
||||
device_type: DeviceInfo.getDeviceType(),
|
||||
device_unique_id: DeviceInfo.getUniqueID(),
|
||||
height: height ? Math.floor(height) : 0,
|
||||
is_emulator: DeviceInfo.isEmulator(),
|
||||
is_emulator: await DeviceInfo.isEmulator(),
|
||||
is_tablet: DeviceInfo.isTablet(),
|
||||
manufacturer: DeviceInfo.getManufacturer(),
|
||||
max_memory: DeviceInfo.getMaxMemory(),
|
||||
manufacturer: await DeviceInfo.getManufacturer(),
|
||||
max_memory: await DeviceInfo.getMaxMemory(),
|
||||
model: DeviceInfo.getModel(),
|
||||
system_name: DeviceInfo.getSystemName(),
|
||||
system_version: DeviceInfo.getSystemVersion(),
|
||||
timezone: DeviceInfo.getTimezone(),
|
||||
timezone: RNLocalize.getTimeZone(),
|
||||
app_version: DeviceInfo.getVersion(),
|
||||
width: width ? Math.floor(width) : 0,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
/* eslint-disable no-import-assign */
|
||||
|
||||
import RNFetchBlob from 'rn-fetch-blob';
|
||||
|
||||
import ImageCacheManager, {getCacheFile, hashCode} from 'app/utils/image_cache_manager';
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// See LICENSE.txt for license information.
|
||||
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import CookieManager from 'react-native-cookies';
|
||||
import CookieManager from '@react-native-community/cookies';
|
||||
|
||||
let mfaPreflightDone = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import DeviceInfo from 'react-native-device-info';
|
||||
|
||||
import {getTimeZone} from 'react-native-localize';
|
||||
import moment from 'moment-timezone';
|
||||
|
||||
export function getDeviceTimezoneAsync() {
|
||||
return DeviceInfo.getTimezoneAsync();
|
||||
export function getDeviceTimezone() {
|
||||
return getTimeZone();
|
||||
}
|
||||
|
||||
export function getDeviceUtcOffset() {
|
||||
|
|
|
|||
|
|
@ -145,8 +145,6 @@
|
|||
"mobile.android.videos_permission_denied_description": "Upload videos to your Mattermost instance or save them to your device. Open Settings to grant Mattermost Read and Write access to your video library.",
|
||||
"mobile.android.videos_permission_denied_title": "{applicationName} would like to access your videos",
|
||||
"mobile.announcement_banner.title": "Announcement",
|
||||
"mobile.authentication_error.message": "Mattermost has encountered an error. Please re-authenticate to start a new session.",
|
||||
"mobile.authentication_error.title": "Authentication Error",
|
||||
"mobile.calendar.dayNames": "Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday",
|
||||
"mobile.calendar.dayNamesShort": "Sun,Mon,Tue,Wed,Thu,Fri,Sat",
|
||||
"mobile.calendar.monthNames": "January,February,March,April,May,June,July,August,September,October,November,December",
|
||||
|
|
@ -512,7 +510,6 @@
|
|||
"more_channels.title": "More Channels",
|
||||
"msg_typing.areTyping": "{users} and {last} are typing...",
|
||||
"msg_typing.isTyping": "{user} is typing...",
|
||||
"navbar_dropdown.logout": "Logout",
|
||||
"navbar.channel_drawer.button": "Channels and teams",
|
||||
"navbar.channel_drawer.hint": "Opens the channels and teams drawer",
|
||||
"navbar.leave": "Leave Channel",
|
||||
|
|
|
|||
|
|
@ -489,7 +489,10 @@ platform :ios do
|
|||
end
|
||||
|
||||
def setup_code_signing
|
||||
disable_automatic_code_signing(path: './ios/Mattermost.xcodeproj')
|
||||
update_code_signing_settings(
|
||||
use_automatic_signing: false,
|
||||
path: './ios/Mattermost.xcodeproj'
|
||||
)
|
||||
|
||||
ENV['MATCH_APP_IDENTIFIER'].split(',').each do |id|
|
||||
target = 'Mattermost'
|
||||
|
|
@ -500,12 +503,13 @@ platform :ios do
|
|||
end
|
||||
|
||||
profile = "sigh_#{id}_#{ENV['MATCH_TYPE']}"
|
||||
config_mode = ENV['BUILD_FOR_RELEASE'] == 'true' ? 'Release' : 'Debug'
|
||||
|
||||
update_project_provisioning(
|
||||
xcodeproj: './ios/Mattermost.xcodeproj',
|
||||
profile: ENV["#{profile}_profile-path"], # optional if you use sigh
|
||||
target_filter: ".*#{target}$", # matches name or type of a target
|
||||
build_configuration: 'Release',
|
||||
build_configuration: config_mode,
|
||||
code_signing_identity: 'iPhone Distribution' # optionally specify the codesigning identity
|
||||
)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -5,21 +5,21 @@ GEM
|
|||
addressable (2.7.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
atomos (0.1.3)
|
||||
aws-eventstream (1.0.3)
|
||||
aws-partitions (1.289.0)
|
||||
aws-sdk-core (3.92.0)
|
||||
aws-eventstream (~> 1.0, >= 1.0.2)
|
||||
aws-eventstream (1.1.0)
|
||||
aws-partitions (1.313.0)
|
||||
aws-sdk-core (3.95.0)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
aws-partitions (~> 1, >= 1.239.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
jmespath (~> 1.0)
|
||||
aws-sdk-kms (1.30.0)
|
||||
aws-sdk-kms (1.31.0)
|
||||
aws-sdk-core (~> 3, >= 3.71.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
aws-sdk-s3 (1.61.1)
|
||||
aws-sdk-s3 (1.64.0)
|
||||
aws-sdk-core (~> 3, >= 3.83.0)
|
||||
aws-sdk-kms (~> 1)
|
||||
aws-sigv4 (~> 1.1)
|
||||
aws-sigv4 (1.1.1)
|
||||
aws-sigv4 (1.1.3)
|
||||
aws-eventstream (~> 1.0, >= 1.0.2)
|
||||
babosa (1.0.3)
|
||||
claide (1.0.3)
|
||||
|
|
@ -35,15 +35,15 @@ GEM
|
|||
dotenv (2.7.5)
|
||||
emoji_regex (1.0.1)
|
||||
excon (0.73.0)
|
||||
faraday (0.17.3)
|
||||
faraday (1.0.1)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
faraday-cookie_jar (0.0.6)
|
||||
faraday (>= 0.7.4)
|
||||
http-cookie (~> 1.0.0)
|
||||
faraday_middleware (0.13.1)
|
||||
faraday (>= 0.7.4, < 1.0)
|
||||
faraday_middleware (1.0.0)
|
||||
faraday (~> 1.0)
|
||||
fastimage (2.1.7)
|
||||
fastlane (2.144.0)
|
||||
fastlane (2.147.0)
|
||||
CFPropertyList (>= 2.3, < 4.0.0)
|
||||
addressable (>= 2.3, < 3.0.0)
|
||||
aws-sdk-s3 (~> 1.0)
|
||||
|
|
@ -54,9 +54,9 @@ GEM
|
|||
dotenv (>= 2.1.1, < 3.0.0)
|
||||
emoji_regex (>= 0.1, < 2.0)
|
||||
excon (>= 0.71.0, < 1.0.0)
|
||||
faraday (~> 0.17)
|
||||
faraday (>= 0.17, < 2.0)
|
||||
faraday-cookie_jar (~> 0.0.6)
|
||||
faraday_middleware (~> 0.13.1)
|
||||
faraday_middleware (>= 0.13.1, < 2.0)
|
||||
fastimage (>= 2.1.0, < 3.0.0)
|
||||
gh_inspector (>= 1.1.2, < 2.0.0)
|
||||
google-api-client (>= 0.29.2, < 0.37.0)
|
||||
|
|
@ -101,20 +101,20 @@ GEM
|
|||
google-cloud-env (1.3.1)
|
||||
faraday (>= 0.17.3, < 2.0)
|
||||
google-cloud-errors (1.0.0)
|
||||
google-cloud-storage (1.25.1)
|
||||
google-cloud-storage (1.26.1)
|
||||
addressable (~> 2.5)
|
||||
digest-crc (~> 0.4)
|
||||
google-api-client (~> 0.33)
|
||||
google-cloud-core (~> 1.2)
|
||||
googleauth (~> 0.9)
|
||||
mini_mime (~> 1.0)
|
||||
googleauth (0.11.0)
|
||||
googleauth (0.12.0)
|
||||
faraday (>= 0.17.3, < 2.0)
|
||||
jwt (>= 1.4, < 3.0)
|
||||
memoist (~> 0.16)
|
||||
multi_json (~> 1.11)
|
||||
os (>= 0.9, < 2.0)
|
||||
signet (~> 0.12)
|
||||
signet (~> 0.14)
|
||||
highline (1.7.10)
|
||||
http-cookie (1.0.3)
|
||||
domain_name (~> 0.5)
|
||||
|
|
@ -133,7 +133,7 @@ GEM
|
|||
naturally (2.2.0)
|
||||
nokogiri (1.10.9)
|
||||
mini_portile2 (~> 2.4.0)
|
||||
os (1.0.1)
|
||||
os (1.1.0)
|
||||
plist (3.5.0)
|
||||
public_suffix (2.0.5)
|
||||
representable (3.0.4)
|
||||
|
|
@ -144,7 +144,7 @@ GEM
|
|||
rouge (2.0.7)
|
||||
rubyzip (1.3.0)
|
||||
security (0.1.3)
|
||||
signet (0.13.2)
|
||||
signet (0.14.0)
|
||||
addressable (~> 2.3)
|
||||
faraday (>= 0.17.3, < 2.0)
|
||||
jwt (>= 1.5, < 3.0)
|
||||
|
|
@ -163,10 +163,10 @@ GEM
|
|||
uber (0.1.0)
|
||||
unf (0.1.4)
|
||||
unf_ext
|
||||
unf_ext (0.0.7.6)
|
||||
unf_ext (0.0.7.7)
|
||||
unicode-display_width (1.7.0)
|
||||
word_wrap (1.0.0)
|
||||
xcodeproj (1.15.0)
|
||||
xcodeproj (1.16.0)
|
||||
CFPropertyList (>= 2.3.3, < 4.0)
|
||||
atomos (~> 0.1.3)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
|
|
|
|||
|
|
@ -930,7 +930,7 @@
|
|||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = EB4F0DF36537B0B21BE962FB /* Pods-Mattermost.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)";
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Mattermost/Mattermost.entitlements;
|
||||
|
|
@ -972,7 +972,7 @@
|
|||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 25BF2BACE89201DE6E585B7E /* Pods-Mattermost.release.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)";
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Mattermost/Mattermost.entitlements;
|
||||
|
|
|
|||
114
ios/Podfile.lock
114
ios/Podfile.lock
|
|
@ -32,12 +32,12 @@ PODS:
|
|||
- libwebp/mux (1.1.0):
|
||||
- libwebp/demux
|
||||
- libwebp/webp (1.1.0)
|
||||
- MMKV (1.1.0):
|
||||
- MMKVCore (~> 1.1.0)
|
||||
- MMKV (1.1.1):
|
||||
- MMKVCore (~> 1.1.1)
|
||||
- MMKVCore (1.1.1)
|
||||
- Permission-Camera (2.0.10):
|
||||
- Permission-Camera (2.1.4):
|
||||
- RNPermissions
|
||||
- Permission-PhotoLibrary (2.0.10):
|
||||
- Permission-PhotoLibrary (2.1.4):
|
||||
- RNPermissions
|
||||
- RCTRequired (0.62.2)
|
||||
- RCTTypeSafety (0.62.2):
|
||||
|
|
@ -45,7 +45,7 @@ PODS:
|
|||
- Folly (= 2018.10.22.00)
|
||||
- RCTRequired (= 0.62.2)
|
||||
- React-Core (= 0.62.2)
|
||||
- RCTYouTube (2.0.0):
|
||||
- RCTYouTube (2.0.1):
|
||||
- React
|
||||
- YoutubePlayer-in-WKWebView (~> 0.3.1)
|
||||
- React (0.62.2):
|
||||
|
|
@ -205,11 +205,11 @@ PODS:
|
|||
- React-cxxreact (= 0.62.2)
|
||||
- React-jsi (= 0.62.2)
|
||||
- React-jsinspector (0.62.2)
|
||||
- react-native-cameraroll (1.5.2):
|
||||
- react-native-cameraroll (1.6.2):
|
||||
- React
|
||||
- react-native-cookies (3.2.0):
|
||||
- react-native-cookies (2.0.9):
|
||||
- React
|
||||
- react-native-document-picker (3.3.2):
|
||||
- react-native-document-picker (3.4.0):
|
||||
- React
|
||||
- react-native-hw-keyboard-event (0.0.4):
|
||||
- React
|
||||
|
|
@ -217,10 +217,10 @@ PODS:
|
|||
- React
|
||||
- react-native-local-auth (1.6.0):
|
||||
- React
|
||||
- react-native-mmkv-storage (0.3.1):
|
||||
- MMKV (= 1.1.0)
|
||||
- react-native-mmkv-storage (0.3.2):
|
||||
- MMKV (= 1.1.1)
|
||||
- React
|
||||
- react-native-netinfo (4.4.0):
|
||||
- react-native-netinfo (5.8.1):
|
||||
- React
|
||||
- react-native-notifications (2.1.7):
|
||||
- React
|
||||
|
|
@ -228,12 +228,14 @@ PODS:
|
|||
- React
|
||||
- react-native-safe-area (0.5.1):
|
||||
- React
|
||||
- react-native-safe-area-context (1.0.0):
|
||||
- React
|
||||
- react-native-video (5.0.2):
|
||||
- React
|
||||
- react-native-video/Video (= 5.0.2)
|
||||
- react-native-video/Video (5.0.2):
|
||||
- React
|
||||
- react-native-webview (7.0.1):
|
||||
- react-native-webview (9.4.0):
|
||||
- React
|
||||
- React-RCTActionSheet (0.62.2):
|
||||
- React-Core/RCTActionSheetHeaders (= 0.62.2)
|
||||
|
|
@ -296,7 +298,7 @@ PODS:
|
|||
- ReactCommon/callinvoker (= 0.62.2)
|
||||
- ReactNativeExceptionHandler (2.10.8):
|
||||
- React
|
||||
- ReactNativeKeyboardTrackingView (5.6.1):
|
||||
- ReactNativeKeyboardTrackingView (5.7.0):
|
||||
- React
|
||||
- ReactNativeNavigation (6.4.0):
|
||||
- React
|
||||
|
|
@ -304,31 +306,37 @@ PODS:
|
|||
- React-RCTText
|
||||
- rn-fetch-blob (0.12.0):
|
||||
- React-Core
|
||||
- RNCAsyncStorage (1.8.1):
|
||||
- RNCAsyncStorage (1.10.1):
|
||||
- React
|
||||
- RNDeviceInfo (2.1.2):
|
||||
- RNCMaskedView (0.1.10):
|
||||
- React
|
||||
- RNDeviceInfo (5.5.7):
|
||||
- React
|
||||
- RNFastImage (8.1.5):
|
||||
- React
|
||||
- SDWebImage (~> 5.0)
|
||||
- SDWebImageWebPCoder (~> 0.4.1)
|
||||
- RNFileViewer (2.1.0):
|
||||
- React
|
||||
- RNGestureHandler (1.6.1):
|
||||
- React
|
||||
- RNKeychain (4.0.5):
|
||||
- RNKeychain (6.0.0):
|
||||
- React
|
||||
- RNPermissions (2.0.10):
|
||||
- RNLocalize (1.4.0):
|
||||
- React
|
||||
- RNReactNativeDocViewer (1.0.0):
|
||||
- RNPermissions (2.1.4):
|
||||
- React
|
||||
- RNReactNativeHapticFeedback (1.9.0):
|
||||
- RNReactNativeHapticFeedback (1.10.0):
|
||||
- React
|
||||
- RNRudderSdk (1.0.0):
|
||||
- React
|
||||
- Rudder (= 1.0.3-beta-4)
|
||||
- RNSentry (1.3.6):
|
||||
- RNScreens (2.7.0):
|
||||
- React
|
||||
- RNSentry (1.3.9):
|
||||
- React
|
||||
- Sentry (~> 4.4.0)
|
||||
- RNSVG (12.0.3):
|
||||
- RNSVG (12.1.0):
|
||||
- React
|
||||
- RNVectorIcons (6.6.0):
|
||||
- React
|
||||
|
|
@ -370,7 +378,7 @@ DEPENDENCIES:
|
|||
- React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
|
||||
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
|
||||
- "react-native-cameraroll (from `../node_modules/@react-native-community/cameraroll`)"
|
||||
- react-native-cookies (from `../node_modules/react-native-cookies/ios`)
|
||||
- "react-native-cookies (from `../node_modules/@react-native-community/cookies`)"
|
||||
- react-native-document-picker (from `../node_modules/react-native-document-picker`)
|
||||
- react-native-hw-keyboard-event (from `../node_modules/react-native-hw-keyboard-event`)
|
||||
- react-native-image-picker (from `../node_modules/react-native-image-picker`)
|
||||
|
|
@ -380,6 +388,7 @@ DEPENDENCIES:
|
|||
- react-native-notifications (from `../node_modules/react-native-notifications`)
|
||||
- react-native-passcode-status (from `../node_modules/react-native-passcode-status`)
|
||||
- react-native-safe-area (from `../node_modules/react-native-safe-area`)
|
||||
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
|
||||
- react-native-video (from `../node_modules/react-native-video`)
|
||||
- react-native-webview (from `../node_modules/react-native-webview`)
|
||||
- React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`)
|
||||
|
|
@ -398,14 +407,17 @@ DEPENDENCIES:
|
|||
- ReactNativeNavigation (from `../node_modules/react-native-navigation`)
|
||||
- rn-fetch-blob (from `../node_modules/rn-fetch-blob`)
|
||||
- "RNCAsyncStorage (from `../node_modules/@react-native-community/async-storage`)"
|
||||
- "RNCMaskedView (from `../node_modules/@react-native-community/masked-view`)"
|
||||
- RNDeviceInfo (from `../node_modules/react-native-device-info`)
|
||||
- RNFastImage (from `../node_modules/react-native-fast-image`)
|
||||
- RNFileViewer (from `../node_modules/react-native-file-viewer`)
|
||||
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
|
||||
- RNKeychain (from `../node_modules/react-native-keychain`)
|
||||
- RNLocalize (from `../node_modules/react-native-localize`)
|
||||
- RNPermissions (from `../node_modules/react-native-permissions`)
|
||||
- RNReactNativeDocViewer (from `../node_modules/react-native-doc-viewer`)
|
||||
- RNReactNativeHapticFeedback (from `../node_modules/react-native-haptic-feedback`)
|
||||
- "RNRudderSdk (from `../node_modules/@rudderstack/rudder-sdk-react-native/ios`)"
|
||||
- RNScreens (from `../node_modules/react-native-screens`)
|
||||
- "RNSentry (from `../node_modules/@sentry/react-native`)"
|
||||
- RNSVG (from `../node_modules/react-native-svg`)
|
||||
- RNVectorIcons (from `../node_modules/react-native-vector-icons`)
|
||||
|
|
@ -469,7 +481,7 @@ EXTERNAL SOURCES:
|
|||
react-native-cameraroll:
|
||||
:path: "../node_modules/@react-native-community/cameraroll"
|
||||
react-native-cookies:
|
||||
:path: "../node_modules/react-native-cookies/ios"
|
||||
:path: "../node_modules/@react-native-community/cookies"
|
||||
react-native-document-picker:
|
||||
:path: "../node_modules/react-native-document-picker"
|
||||
react-native-hw-keyboard-event:
|
||||
|
|
@ -488,6 +500,8 @@ EXTERNAL SOURCES:
|
|||
:path: "../node_modules/react-native-passcode-status"
|
||||
react-native-safe-area:
|
||||
:path: "../node_modules/react-native-safe-area"
|
||||
react-native-safe-area-context:
|
||||
:path: "../node_modules/react-native-safe-area-context"
|
||||
react-native-video:
|
||||
:path: "../node_modules/react-native-video"
|
||||
react-native-webview:
|
||||
|
|
@ -522,22 +536,28 @@ EXTERNAL SOURCES:
|
|||
:path: "../node_modules/rn-fetch-blob"
|
||||
RNCAsyncStorage:
|
||||
:path: "../node_modules/@react-native-community/async-storage"
|
||||
RNCMaskedView:
|
||||
:path: "../node_modules/@react-native-community/masked-view"
|
||||
RNDeviceInfo:
|
||||
:path: "../node_modules/react-native-device-info"
|
||||
RNFastImage:
|
||||
:path: "../node_modules/react-native-fast-image"
|
||||
RNFileViewer:
|
||||
:path: "../node_modules/react-native-file-viewer"
|
||||
RNGestureHandler:
|
||||
:path: "../node_modules/react-native-gesture-handler"
|
||||
RNKeychain:
|
||||
:path: "../node_modules/react-native-keychain"
|
||||
RNLocalize:
|
||||
:path: "../node_modules/react-native-localize"
|
||||
RNPermissions:
|
||||
:path: "../node_modules/react-native-permissions"
|
||||
RNReactNativeDocViewer:
|
||||
:path: "../node_modules/react-native-doc-viewer"
|
||||
RNReactNativeHapticFeedback:
|
||||
:path: "../node_modules/react-native-haptic-feedback"
|
||||
RNRudderSdk:
|
||||
:path: "../node_modules/@rudderstack/rudder-sdk-react-native/ios"
|
||||
RNScreens:
|
||||
:path: "../node_modules/react-native-screens"
|
||||
RNSentry:
|
||||
:path: "../node_modules/@sentry/react-native"
|
||||
RNSVG:
|
||||
|
|
@ -557,13 +577,13 @@ SPEC CHECKSUMS:
|
|||
glog: 1f3da668190260b06b429bb211bfbee5cd790c28
|
||||
jail-monkey: d7c5048b2336f22ee9c9e0efa145f1f917338ea9
|
||||
libwebp: 946cb3063cea9236285f7e9a8505d806d30e07f3
|
||||
MMKV: 7bb6c30f9ff2ea45bc2398c86e66dd1cb63cfe20
|
||||
MMKV: 5eb44526fcf38152328ebfeff5ec585972ace00d
|
||||
MMKVCore: 2748bf702287a814a6c514d054033e41e07f5c0f
|
||||
Permission-Camera: 8f0e5decca5f28f70f28a8dc31f012c9bad40ad8
|
||||
Permission-PhotoLibrary: b209bf23b784c9e1409a57d81c6d11ab1d3079c1
|
||||
Permission-Camera: 3ed116545ee8806cd706bca0e1a9a2c3cd36c6bd
|
||||
Permission-PhotoLibrary: 56e71522b008d9abca150680c1f8050f267cdffb
|
||||
RCTRequired: cec6a34b3ac8a9915c37e7e4ad3aa74726ce4035
|
||||
RCTTypeSafety: 93006131180074cffa227a1075802c89a49dd4ce
|
||||
RCTYouTube: 5e94bfa005371c41d307f3f93c51b3e8eabfb0c8
|
||||
RCTYouTube: 7ff7d42f5ed42d185198681e967fd2c2b661375d
|
||||
React: 29a8b1a02bd764fb7644ef04019270849b9a7ac3
|
||||
React-Core: b12bffb3f567fdf99510acb716ef1abd426e0e05
|
||||
React-CoreModules: 4a9b87bbe669d6c3173c0132c3328e3b000783d0
|
||||
|
|
@ -571,19 +591,20 @@ SPEC CHECKSUMS:
|
|||
React-jsi: b6dc94a6a12ff98e8877287a0b7620d365201161
|
||||
React-jsiexecutor: 1540d1c01bb493ae3124ed83351b1b6a155db7da
|
||||
React-jsinspector: 512e560d0e985d0e8c479a54a4e5c147a9c83493
|
||||
react-native-cameraroll: 81c6c271b5b853da398ccecc7ad6a5f765fd3001
|
||||
react-native-cookies: 854d59c4135c70b92a02ca4930e68e4e2eb58150
|
||||
react-native-document-picker: 6acd41af22988cf349848678fdaa294d4448478e
|
||||
react-native-cameraroll: 94bec91c68b94ac946c61b497b594bb38692c41b
|
||||
react-native-cookies: bc1f91a504ee091f1998a1b6c7ff4b7a9ed5b80e
|
||||
react-native-document-picker: d694111879537cec2c258a1dcd2243d9df746824
|
||||
react-native-hw-keyboard-event: b517cefb8d5c659a38049c582de85ff43337dc53
|
||||
react-native-image-picker: 668e72d0277dc8c12ae90e835507c1eddd2e4f85
|
||||
react-native-local-auth: 359af242caa1e5c501ac9dfe33b1e238ad8f08c6
|
||||
react-native-mmkv-storage: d413e1e00b1f410a744e1d547a912a1f87e67260
|
||||
react-native-netinfo: 892a5130be97ff8bb69c523739c424a2ffc296d1
|
||||
react-native-mmkv-storage: 49389227471de5258b4e5bae7857bfe0ad02c8f7
|
||||
react-native-netinfo: ae21a6ab293d6c75af0c17c562ef37a931218886
|
||||
react-native-notifications: 24706907104a0f00c35c4bde7e0ca76a50f730e1
|
||||
react-native-passcode-status: 88c4f6e074328bc278bd127646b6c694ad5a530a
|
||||
react-native-safe-area: e8230b0017d76c00de6b01e2412dcf86b127c6a3
|
||||
react-native-safe-area-context: 5f3e081f937ab7c44c179d551f332fa494cfcf8f
|
||||
react-native-video: 961749da457e73bf0b5565edfbaffc25abfb8974
|
||||
react-native-webview: 0d1c2b4e7ffb0543a74fa0512f2f8dc5fb0e49e2
|
||||
react-native-webview: 0e2881d2e3e72ad52a82445c1a116c43205fd471
|
||||
React-RCTActionSheet: f41ea8a811aac770e0cc6e0ad6b270c644ea8b7c
|
||||
React-RCTAnimation: 49ab98b1c1ff4445148b72a3d61554138565bad0
|
||||
React-RCTBlob: a332773f0ebc413a0ce85942a55b064471587a71
|
||||
|
|
@ -595,20 +616,23 @@ SPEC CHECKSUMS:
|
|||
React-RCTVibration: 4356114dbcba4ce66991096e51a66e61eda51256
|
||||
ReactCommon: ed4e11d27609d571e7eee8b65548efc191116eb3
|
||||
ReactNativeExceptionHandler: 8025d98049c25f186835a3af732dd7c9974d6dce
|
||||
ReactNativeKeyboardTrackingView: a240a6a0dba852bb107109a7ec7e98b884055977
|
||||
ReactNativeKeyboardTrackingView: 02137fac3b2ebd330d74fa54ead48b14750a2306
|
||||
ReactNativeNavigation: 667586f6924fbd09512e2933fe70497db914b758
|
||||
rn-fetch-blob: 17961aec08caae68bb8fc0e5b40f93b3acfa6932
|
||||
RNCAsyncStorage: 00bdf63f7f1e0f11d3323533dba4f222e58bf092
|
||||
RNDeviceInfo: fd8296de6fca8b743cdc499b896f48e8a9f1faf5
|
||||
RNCAsyncStorage: f640ddf9266df777c38e112ea5881ead7188b59c
|
||||
RNCMaskedView: f5c7d14d6847b7b44853f7acb6284c1da30a3459
|
||||
RNDeviceInfo: 498ccbf8b1361fe858581e3c1193ecee1a031e62
|
||||
RNFastImage: 35ae972d6727c84ee3f5c6897e07f84d0a3445e9
|
||||
RNFileViewer: 3600e85d326dadfd0fd367eb38fcb4300b699b49
|
||||
RNGestureHandler: 8f09cd560f8d533eb36da5a6c5a843af9f056b38
|
||||
RNKeychain: 840f8e6f13be0576202aefcdffd26a4f54bfe7b5
|
||||
RNPermissions: 8afd37dbc1be65748363c6a90caffd1806567651
|
||||
RNReactNativeDocViewer: 571c6ac38483531b8fb521d02a6ba54652ed10a7
|
||||
RNReactNativeHapticFeedback: 2566b468cc8d0e7bb2f84b23adc0f4614594d071
|
||||
RNKeychain: bf2d7e9a0ae7a073c07770dd2aa6d11c67581733
|
||||
RNLocalize: fc27ee5878ce5a3af73873fb2d8e866e0d1e6d84
|
||||
RNPermissions: 8ca17fd6c822eea589fe84709d9426e05cc39c39
|
||||
RNReactNativeHapticFeedback: 22c5ecf474428766c6b148f96f2ff6155cd7225e
|
||||
RNRudderSdk: 3abdcc4b145b3db6571827b0fc7af4e75a96af13
|
||||
RNSentry: d892cbdee165cc6159d71e2a7954efdb8a361918
|
||||
RNSVG: 7e16ddfc6e00d5aa69c9eb83e699bcce5dcb85d4
|
||||
RNScreens: cf198f915f8a2bf163de94ca9f5bfc8d326c3706
|
||||
RNSentry: 9c9783b13fb5cba387fff55f085cc1da3854ce71
|
||||
RNSVG: ce9d996113475209013317e48b05c21ee988d42e
|
||||
RNVectorIcons: 0bb4def82230be1333ddaeee9fcba45f0b288ed4
|
||||
Rudder: 358a71278045a608ae4b081b37a465ffb65c129d
|
||||
SDWebImage: 84000f962cbfa70c07f19d2234cbfcf5d779b5dc
|
||||
|
|
|
|||
8070
package-lock.json
generated
8070
package-lock.json
generated
File diff suppressed because it is too large
Load diff
117
package.json
117
package.json
|
|
@ -7,119 +7,124 @@
|
|||
"license": "Apache 2.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@babel/runtime": "7.9.2",
|
||||
"@react-native-community/async-storage": "1.8.1",
|
||||
"@react-native-community/cameraroll": "1.5.2",
|
||||
"@react-native-community/netinfo": "4.4.0",
|
||||
"@babel/runtime": "7.9.6",
|
||||
"@react-native-community/async-storage": "1.10.1",
|
||||
"@react-native-community/cameraroll": "1.6.2",
|
||||
"@react-native-community/cookies": "2.0.9",
|
||||
"@react-native-community/masked-view": "0.1.10",
|
||||
"@react-native-community/netinfo": "5.8.1",
|
||||
"@react-navigation/native": "5.3.2",
|
||||
"@react-navigation/stack": "5.3.6",
|
||||
"@rudderstack/rudder-sdk-react-native": "0.1.2",
|
||||
"@sentry/react-native": "1.3.6",
|
||||
"@sentry/react-native": "1.3.9",
|
||||
"analytics-react-native": "1.2.0",
|
||||
"commonmark": "github:mattermost/commonmark.js#f6ab98dede6ce4b4e7adea140ac77249bfb2d6ce",
|
||||
"commonmark-react-renderer": "github:mattermost/commonmark-react-renderer#3a2ac19cab725ad28b170fdc1d397dddedcf87eb",
|
||||
"core-js": "3.6.4",
|
||||
"deep-equal": "2.0.1",
|
||||
"core-js": "3.6.5",
|
||||
"deep-equal": "2.0.3",
|
||||
"deepmerge": "4.2.2",
|
||||
"emoji-regex": "8.0.0",
|
||||
"emoji-regex": "9.0.0",
|
||||
"form-data": "3.0.0",
|
||||
"fuse.js": "3.6.1",
|
||||
"fuse.js": "6.0.0",
|
||||
"intl": "1.2.5",
|
||||
"jail-monkey": "2.3.2",
|
||||
"mime-db": "1.43.0",
|
||||
"moment-timezone": "0.5.26",
|
||||
"mime-db": "1.44.0",
|
||||
"moment-timezone": "0.5.29",
|
||||
"prop-types": "15.7.2",
|
||||
"react": "16.13.0",
|
||||
"react": "16.13.1",
|
||||
"react-intl": "2.8.0",
|
||||
"react-native": "0.62.2",
|
||||
"react-native-android-open-settings": "1.3.0",
|
||||
"react-native-animatable": "1.3.3",
|
||||
"react-native-button": "2.4.0",
|
||||
"react-native-calendars": "1.264.0",
|
||||
"react-native-button": "3.0.1",
|
||||
"react-native-calendars": "1.265.0",
|
||||
"react-native-circular-progress": "1.3.6",
|
||||
"react-native-cookies": "github:mattermost/react-native-cookies#b35bafc388ae09c83bd875e887daf6a0755e0b40",
|
||||
"react-native-device-info": "github:mattermost/react-native-device-info#f7175f10822d8f66b9806206e3313eaf2f4aabc6",
|
||||
"react-native-doc-viewer": "github:mattermost/react-native-doc-viewer#c913e54ec8e4a60753bc7dd39256fa4be8229d19",
|
||||
"react-native-document-picker": "3.3.2",
|
||||
"react-native-elements": "1.2.7",
|
||||
"react-native-device-info": "5.5.7",
|
||||
"react-native-document-picker": "3.4.0",
|
||||
"react-native-elements": "2.0.0",
|
||||
"react-native-exception-handler": "2.10.8",
|
||||
"react-native-fast-image": "8.1.5",
|
||||
"react-native-file-viewer": "2.1.0",
|
||||
"react-native-gesture-handler": "1.6.1",
|
||||
"react-native-haptic-feedback": "1.9.0",
|
||||
"react-native-haptic-feedback": "1.10.0",
|
||||
"react-native-hw-keyboard-event": "0.0.4",
|
||||
"react-native-image-gallery": "github:mattermost/react-native-image-gallery#c1a9f7118e90cc87d47620bc0584c9cac4b0cf38",
|
||||
"react-native-image-picker": "2.3.1",
|
||||
"react-native-keyboard-aware-scroll-view": "0.9.1",
|
||||
"react-native-keyboard-tracking-view": "5.6.1",
|
||||
"react-native-keychain": "4.0.5",
|
||||
"react-native-keyboard-tracking-view": "5.7.0",
|
||||
"react-native-keychain": "6.0.0",
|
||||
"react-native-linear-gradient": "2.5.6",
|
||||
"react-native-local-auth": "1.6.0",
|
||||
"react-native-mmkv-storage": "0.3.1",
|
||||
"react-native-localize": "1.4.0",
|
||||
"react-native-mmkv-storage": "0.3.2",
|
||||
"react-native-navigation": "6.4.0",
|
||||
"react-native-notifications": "2.1.7",
|
||||
"react-native-passcode-status": "1.1.2",
|
||||
"react-native-permissions": "2.0.10",
|
||||
"react-native-permissions": "2.1.4",
|
||||
"react-native-safe-area": "0.5.1",
|
||||
"react-native-safe-area-context": "1.0.0",
|
||||
"react-native-screens": "2.7.0",
|
||||
"react-native-section-list-get-item-layout": "2.2.3",
|
||||
"react-native-slider": "0.11.0",
|
||||
"react-native-status-bar-size": "0.3.3",
|
||||
"react-native-svg": "12.0.3",
|
||||
"react-native-svg": "12.1.0",
|
||||
"react-native-v8": "0.62.2-patch.1",
|
||||
"react-native-vector-icons": "6.6.0",
|
||||
"react-native-video": "5.0.2",
|
||||
"react-native-webview": "github:mattermost/react-native-webview#b5e22940a613869d3999feac9451ee65352f4fbe",
|
||||
"react-native-youtube": "2.0.0",
|
||||
"react-navigation": "4.0.10",
|
||||
"react-navigation-stack": "1.9.4",
|
||||
"react-native-webview": "9.4.0",
|
||||
"react-native-youtube": "2.0.1",
|
||||
"react-redux": "7.2.0",
|
||||
"redux": "4.0.5",
|
||||
"redux-action-buffer": "1.2.0",
|
||||
"redux-batched-actions": "0.4.1",
|
||||
"redux-batched-actions": "0.5.0",
|
||||
"redux-persist": "6.0.0",
|
||||
"redux-persist-transform-filter": "0.0.20",
|
||||
"redux-reset": "0.3.0",
|
||||
"redux-thunk": "2.3.0",
|
||||
"reselect": "4.0.0",
|
||||
"rn-fetch-blob": "0.12.0",
|
||||
"rn-placeholder": "github:mattermost/rn-placeholder#02c629c65d0123a2eee623ada0fd17186415d3c3",
|
||||
"semver": "7.1.3",
|
||||
"serialize-error": "5.0.0",
|
||||
"rn-placeholder": "3.0.0",
|
||||
"semver": "7.3.2",
|
||||
"serialize-error": "7.0.1",
|
||||
"shallow-equals": "1.0.0",
|
||||
"tinycolor2": "1.4.1",
|
||||
"url-parse": "1.4.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "7.8.4",
|
||||
"@babel/core": "7.9.0",
|
||||
"@babel/plugin-transform-runtime": "7.9.0",
|
||||
"@babel/preset-env": "7.9.0",
|
||||
"@babel/core": "7.9.6",
|
||||
"@babel/plugin-transform-runtime": "7.9.6",
|
||||
"@babel/preset-env": "7.9.6",
|
||||
"@babel/register": "7.9.0",
|
||||
"@testing-library/react-native": "5.0.3",
|
||||
"@types/enzyme": "3.10.5",
|
||||
"@types/enzyme-adapter-react-16": "1.0.6",
|
||||
"@types/jest": "25.1.4",
|
||||
"@types/jest": "25.2.2",
|
||||
"@types/moment-timezone": "0.5.13",
|
||||
"@types/react": "16.9.27",
|
||||
"@types/react-native": "0.62.0",
|
||||
"@types/react": "16.9.35",
|
||||
"@types/react-native": "0.62.10",
|
||||
"@types/react-test-renderer": "16.9.2",
|
||||
"@types/shallow-equals": "1.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "2.25.0",
|
||||
"@typescript-eslint/parser": "2.25.0",
|
||||
"@typescript-eslint/eslint-plugin": "2.33.0",
|
||||
"@typescript-eslint/parser": "2.33.0",
|
||||
"babel-eslint": "10.1.0",
|
||||
"babel-jest": "25.2.3",
|
||||
"babel-jest": "26.0.1",
|
||||
"babel-plugin-module-resolver": "4.0.0",
|
||||
"babel-plugin-transform-remove-console": "6.9.4",
|
||||
"deep-freeze": "0.0.1",
|
||||
"enzyme": "3.11.0",
|
||||
"enzyme-adapter-react-16": "1.15.2",
|
||||
"enzyme-to-json": "3.4.4",
|
||||
"eslint": "6.8.0",
|
||||
"eslint": "7.0.0",
|
||||
"eslint-plugin-header": "3.0.0",
|
||||
"eslint-plugin-jest": "23.8.2",
|
||||
"eslint-plugin-jest": "23.13.0",
|
||||
"eslint-plugin-mattermost": "github:mattermost/eslint-plugin-mattermost#070ce792d105482ffb2b27cfc0b7e78b3d20acee",
|
||||
"eslint-plugin-react": "7.19.0",
|
||||
"eslint-plugin-react": "7.20.0",
|
||||
"harmony-reflect": "1.6.1",
|
||||
"husky": "4.2.3",
|
||||
"husky": "4.2.5",
|
||||
"isomorphic-fetch": "2.2.1",
|
||||
"jest": "25.2.3",
|
||||
"jest-cli": "25.2.3",
|
||||
"jest": "26.0.1",
|
||||
"jest-cli": "26.0.1",
|
||||
"jest-enzyme": "7.1.2",
|
||||
"jetifier": "1.6.5",
|
||||
"jsdom-global": "3.0.2",
|
||||
|
|
@ -128,17 +133,17 @@
|
|||
"mock-async-storage": "2.2.0",
|
||||
"mock-socket": "9.0.3",
|
||||
"nock": "12.0.3",
|
||||
"nyc": "15.0.0",
|
||||
"patch-package": "6.2.1",
|
||||
"react-dom": "16.13.0",
|
||||
"react-test-renderer": "16.13.0",
|
||||
"nyc": "15.0.1",
|
||||
"patch-package": "6.2.2",
|
||||
"react-dom": "16.13.1",
|
||||
"react-test-renderer": "16.13.1",
|
||||
"redux-mock-store": "1.5.4",
|
||||
"redux-persist-node-storage": "2.0.0",
|
||||
"socketcluster": "16.0.1",
|
||||
"ts-jest": "25.5.0",
|
||||
"typescript": "3.8.3",
|
||||
"underscore": "1.9.2",
|
||||
"util": "0.12.2"
|
||||
"ts-jest": "26.0.0",
|
||||
"typescript": "3.9.2",
|
||||
"underscore": "1.10.2",
|
||||
"util": "0.12.3"
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
|
|
|
|||
|
|
@ -220,38 +220,20 @@ module.exports = [
|
|||
'node_modules/@babel/runtime/helpers/typeof.js',
|
||||
'node_modules/@babel/runtime/helpers/unsupportedIterableToArray.js',
|
||||
'node_modules/@babel/runtime/helpers/wrapNativeSuper.js',
|
||||
'node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js',
|
||||
'node_modules/@babel/runtime/regenerator/index.js',
|
||||
'node_modules/@react-native-community/async-storage/lib/AsyncStorage.js',
|
||||
'node_modules/@react-native-community/async-storage/lib/hooks.js',
|
||||
'node_modules/@react-native-community/async-storage/lib/index.js',
|
||||
'node_modules/@react-native-community/netinfo/src/index.ts',
|
||||
'node_modules/@react-native-community/netinfo/src/internal/deprecatedState.ts',
|
||||
'node_modules/@react-native-community/netinfo/src/internal/deprecatedTypes.ts',
|
||||
'node_modules/@react-native-community/netinfo/src/internal/deprecatedUtils.ts',
|
||||
'node_modules/@react-native-community/netinfo/src/internal/internetReachability.ts',
|
||||
'node_modules/@react-native-community/netinfo/src/internal/nativeInterface.ts',
|
||||
'node_modules/@react-native-community/netinfo/src/internal/state.ts',
|
||||
'node_modules/@react-native-community/netinfo/src/internal/types.ts',
|
||||
'node_modules/@react-native-community/netinfo/src/internal/utils.ts',
|
||||
'node_modules/@react-native-community/cookies/index.js',
|
||||
'node_modules/anser/lib/index.js',
|
||||
'node_modules/base-64/base64.js',
|
||||
'node_modules/base64-js/index.js',
|
||||
'node_modules/buffer/index.js',
|
||||
'node_modules/clone/clone.js',
|
||||
'node_modules/color-convert/conversions.js',
|
||||
'node_modules/color-convert/index.js',
|
||||
'node_modules/color-convert/route.js',
|
||||
'node_modules/color-name/index.js',
|
||||
'node_modules/color-string/index.js',
|
||||
'node_modules/color/index.js',
|
||||
'node_modules/create-react-class/factory.js',
|
||||
'node_modules/create-react-class/index.js',
|
||||
'node_modules/create-react-class/node_modules/fbjs/lib/emptyFunction.js',
|
||||
'node_modules/create-react-class/node_modules/fbjs/lib/emptyObject.js',
|
||||
'node_modules/create-react-class/node_modules/fbjs/lib/invariant.js',
|
||||
'node_modules/create-react-class/node_modules/fbjs/lib/warning.js',
|
||||
'node_modules/component-emitter/index.js',
|
||||
'node_modules/deepmerge/dist/cjs.js',
|
||||
'node_modules/event-target-shim/dist/event-target-shim.js',
|
||||
'node_modules/eventemitter3/index.js',
|
||||
|
|
@ -265,7 +247,6 @@ module.exports = [
|
|||
'node_modules/fbjs/lib/warning.js',
|
||||
'node_modules/harmony-reflect/reflect.js',
|
||||
'node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js',
|
||||
'node_modules/inherits/inherits_browser.js',
|
||||
'node_modules/intl-format-cache/dist/index.js',
|
||||
'node_modules/intl-format-cache/index.js',
|
||||
'node_modules/intl-messageformat-parser/index.js',
|
||||
|
|
@ -289,8 +270,6 @@ module.exports = [
|
|||
'node_modules/intl/lib/core.js',
|
||||
'node_modules/intl/locale-data/complete.js',
|
||||
'node_modules/invariant/browser.js',
|
||||
'node_modules/is-arguments/index.js',
|
||||
'node_modules/is-generator-function/index.js',
|
||||
'node_modules/lodash.clonedeep/index.js',
|
||||
'node_modules/lodash.forin/index.js',
|
||||
'node_modules/lodash.get/index.js',
|
||||
|
|
@ -379,7 +358,6 @@ module.exports = [
|
|||
'node_modules/lodash/_createAssigner.js',
|
||||
'node_modules/lodash/_createBaseEach.js',
|
||||
'node_modules/lodash/_createBaseFor.js',
|
||||
'node_modules/lodash/_createSet.js',
|
||||
'node_modules/lodash/_customOmitClone.js',
|
||||
'node_modules/lodash/_defineProperty.js',
|
||||
'node_modules/lodash/_equalArrays.js',
|
||||
|
|
@ -485,7 +463,6 @@ module.exports = [
|
|||
'node_modules/lodash/map.js',
|
||||
'node_modules/lodash/memoize.js',
|
||||
'node_modules/lodash/merge.js',
|
||||
'node_modules/lodash/noop.js',
|
||||
'node_modules/lodash/omit.js',
|
||||
'node_modules/lodash/pick.js',
|
||||
'node_modules/lodash/property.js',
|
||||
|
|
@ -519,11 +496,15 @@ module.exports = [
|
|||
'node_modules/react-intl/lib/index.js',
|
||||
'node_modules/react-intl/locale-data/en.js',
|
||||
'node_modules/react-intl/locale-data/index.js',
|
||||
'node_modules/react-is/cjs/react-is.production.js',
|
||||
'node_modules/react-is/cjs/react-is.production.min.js',
|
||||
'node_modules/react-is/index.js',
|
||||
'node_modules/react-lifecycles-compat/react-lifecycles-compat.cjs.js',
|
||||
'node_modules/react-native-cookies/index.js',
|
||||
'node_modules/react-native-device-info/deviceinfo.js',
|
||||
'node_modules/react-native-device-info/src/index.ts',
|
||||
'node_modules/react-native-device-info/src/internal/asyncHookWrappers.ts',
|
||||
'node_modules/react-native-device-info/src/internal/devicesWithNotch.ts',
|
||||
'node_modules/react-native-device-info/src/internal/nativeInterface.ts',
|
||||
'node_modules/react-native-gesture-handler/GestureButtons.js',
|
||||
'node_modules/react-native-gesture-handler/GestureComponents.js',
|
||||
'node_modules/react-native-gesture-handler/GestureHandler.js',
|
||||
'node_modules/react-native-gesture-handler/GestureHandlerButton.js',
|
||||
'node_modules/react-native-gesture-handler/GestureHandlerPropTypes.js',
|
||||
|
|
@ -532,13 +513,14 @@ module.exports = [
|
|||
'node_modules/react-native-gesture-handler/NativeViewGestureHandler.js',
|
||||
'node_modules/react-native-gesture-handler/PlatformConstants.js',
|
||||
'node_modules/react-native-gesture-handler/RNGestureHandlerModule.js',
|
||||
'node_modules/react-native-gesture-handler/State.js',
|
||||
'node_modules/react-native-gesture-handler/createHandler.js',
|
||||
'node_modules/react-native-gesture-handler/createNativeWrapper.js',
|
||||
'node_modules/react-native-gesture-handler/gestureHandlerRootHOC.js',
|
||||
'node_modules/react-native-gesture-handler/index.js',
|
||||
'node_modules/react-native-haptic-feedback/index.js',
|
||||
'node_modules/react-native-keychain/index.js',
|
||||
'node_modules/react-native-localize/lib/commonjs/index.js',
|
||||
'node_modules/react-native-localize/lib/commonjs/module.js',
|
||||
'node_modules/react-native-mmkv-storage/index.js',
|
||||
'node_modules/react-native-mmkv-storage/src/api.js',
|
||||
'node_modules/react-native-mmkv-storage/src/encryption.js',
|
||||
|
|
@ -747,7 +729,6 @@ module.exports = [
|
|||
'node_modules/react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore.js',
|
||||
'node_modules/react-native/Libraries/ReactPrivate/ReactNativePrivateInterface.js',
|
||||
'node_modules/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js',
|
||||
'node_modules/react-native/Libraries/Renderer/shims/NativeMethodsMixin.js',
|
||||
'node_modules/react-native/Libraries/Renderer/shims/ReactNative.js',
|
||||
'node_modules/react-native/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js',
|
||||
'node_modules/react-native/Libraries/Renderer/shims/createReactNativeComponentClass.js',
|
||||
|
|
@ -764,6 +745,7 @@ module.exports = [
|
|||
'node_modules/react-native/Libraries/TurboModule/TurboModuleRegistry.js',
|
||||
'node_modules/react-native/Libraries/UTFSequence.js',
|
||||
'node_modules/react-native/Libraries/Utilities/BackHandler.android.js',
|
||||
'node_modules/react-native/Libraries/Utilities/DeviceInfo.js',
|
||||
'node_modules/react-native/Libraries/Utilities/Dimensions.js',
|
||||
'node_modules/react-native/Libraries/Utilities/GlobalPerformanceLogger.js',
|
||||
'node_modules/react-native/Libraries/Utilities/HMRClient.js',
|
||||
|
|
@ -911,18 +893,16 @@ module.exports = [
|
|||
'node_modules/semver/ranges/min-satisfying.js',
|
||||
'node_modules/semver/ranges/min-version.js',
|
||||
'node_modules/semver/ranges/outside.js',
|
||||
'node_modules/semver/ranges/simplify.js',
|
||||
'node_modules/semver/ranges/to-comparators.js',
|
||||
'node_modules/semver/ranges/valid.js',
|
||||
'node_modules/serialize-error/index.js',
|
||||
'node_modules/shallow-equals/index.js',
|
||||
'node_modules/simple-swizzle/index.js',
|
||||
'node_modules/stacktrace-parser/dist/stack-trace-parser.cjs.js',
|
||||
'node_modules/simple-swizzle/node_modules/is-arrayish/index.js',
|
||||
'node_modules/symbol-observable/lib/index.js',
|
||||
'node_modules/symbol-observable/lib/ponyfill.js',
|
||||
'node_modules/url-parse/index.js',
|
||||
'node_modules/util/support/isBufferBrowser.js',
|
||||
'node_modules/util/support/types.js',
|
||||
'node_modules/util/util.js',
|
||||
'share_extension/android/actions/index.js',
|
||||
'share_extension/android/index.js',
|
||||
];
|
||||
|
|
@ -218,28 +218,20 @@ module.exports = [
|
|||
'./node_modules/node_modules/@babel/runtime/helpers/typeof.js',
|
||||
'./node_modules/node_modules/@babel/runtime/helpers/unsupportedIterableToArray.js',
|
||||
'./node_modules/node_modules/@babel/runtime/helpers/wrapNativeSuper.js',
|
||||
'./node_modules/node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js',
|
||||
'./node_modules/node_modules/@babel/runtime/regenerator/index.js',
|
||||
'./node_modules/node_modules/@react-native-community/async-storage/lib/AsyncStorage.js',
|
||||
'./node_modules/node_modules/@react-native-community/async-storage/lib/hooks.js',
|
||||
'./node_modules/node_modules/@react-native-community/async-storage/lib/index.js',
|
||||
'./node_modules/node_modules/@react-native-community/cookies/index.js',
|
||||
'./node_modules/node_modules/anser/lib/index.js',
|
||||
'./node_modules/node_modules/base-64/base64.js',
|
||||
'./node_modules/node_modules/base64-js/index.js',
|
||||
'./node_modules/node_modules/buffer/index.js',
|
||||
'./node_modules/node_modules/clone/clone.js',
|
||||
'./node_modules/node_modules/color-convert/conversions.js',
|
||||
'./node_modules/node_modules/color-convert/index.js',
|
||||
'./node_modules/node_modules/color-convert/route.js',
|
||||
'./node_modules/node_modules/color-name/index.js',
|
||||
'./node_modules/node_modules/color-string/index.js',
|
||||
'./node_modules/node_modules/color/index.js',
|
||||
'./node_modules/node_modules/create-react-class/factory.js',
|
||||
'./node_modules/node_modules/create-react-class/index.js',
|
||||
'./node_modules/node_modules/create-react-class/node_modules/fbjs/lib/emptyFunction.js',
|
||||
'./node_modules/node_modules/create-react-class/node_modules/fbjs/lib/emptyObject.js',
|
||||
'./node_modules/node_modules/create-react-class/node_modules/fbjs/lib/invariant.js',
|
||||
'./node_modules/node_modules/create-react-class/node_modules/fbjs/lib/warning.js',
|
||||
'./node_modules/node_modules/component-emitter/index.js',
|
||||
'./node_modules/node_modules/deepmerge/dist/cjs.js',
|
||||
'./node_modules/node_modules/event-target-shim/dist/event-target-shim.js',
|
||||
'./node_modules/node_modules/eventemitter3/index.js',
|
||||
|
|
@ -253,7 +245,6 @@ module.exports = [
|
|||
'./node_modules/node_modules/fbjs/lib/warning.js',
|
||||
'./node_modules/node_modules/harmony-reflect/reflect.js',
|
||||
'./node_modules/node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js',
|
||||
'./node_modules/node_modules/inherits/inherits_browser.js',
|
||||
'./node_modules/node_modules/intl-format-cache/dist/index.js',
|
||||
'./node_modules/node_modules/intl-format-cache/index.js',
|
||||
'./node_modules/node_modules/intl-messageformat-parser/index.js',
|
||||
|
|
@ -277,8 +268,6 @@ module.exports = [
|
|||
'./node_modules/node_modules/intl/lib/core.js',
|
||||
'./node_modules/node_modules/intl/locale-data/complete.js',
|
||||
'./node_modules/node_modules/invariant/browser.js',
|
||||
'./node_modules/node_modules/is-arguments/index.js',
|
||||
'./node_modules/node_modules/is-generator-function/index.js',
|
||||
'./node_modules/node_modules/lodash.clonedeep/index.js',
|
||||
'./node_modules/node_modules/lodash.forin/index.js',
|
||||
'./node_modules/node_modules/lodash.get/index.js',
|
||||
|
|
@ -367,7 +356,6 @@ module.exports = [
|
|||
'./node_modules/node_modules/lodash/_createAssigner.js',
|
||||
'./node_modules/node_modules/lodash/_createBaseEach.js',
|
||||
'./node_modules/node_modules/lodash/_createBaseFor.js',
|
||||
'./node_modules/node_modules/lodash/_createSet.js',
|
||||
'./node_modules/node_modules/lodash/_customOmitClone.js',
|
||||
'./node_modules/node_modules/lodash/_defineProperty.js',
|
||||
'./node_modules/node_modules/lodash/_equalArrays.js',
|
||||
|
|
@ -473,7 +461,6 @@ module.exports = [
|
|||
'./node_modules/node_modules/lodash/map.js',
|
||||
'./node_modules/node_modules/lodash/memoize.js',
|
||||
'./node_modules/node_modules/lodash/merge.js',
|
||||
'./node_modules/node_modules/lodash/noop.js',
|
||||
'./node_modules/node_modules/lodash/omit.js',
|
||||
'./node_modules/node_modules/lodash/pick.js',
|
||||
'./node_modules/node_modules/lodash/property.js',
|
||||
|
|
@ -506,11 +493,15 @@ module.exports = [
|
|||
'./node_modules/node_modules/react-intl/lib/index.js',
|
||||
'./node_modules/node_modules/react-intl/locale-data/en.js',
|
||||
'./node_modules/node_modules/react-intl/locale-data/index.js',
|
||||
'./node_modules/node_modules/react-is/cjs/react-is.production.js',
|
||||
'./node_modules/node_modules/react-is/cjs/react-is.production.min.js',
|
||||
'./node_modules/node_modules/react-is/index.js',
|
||||
'./node_modules/node_modules/react-lifecycles-compat/react-lifecycles-compat.cjs.js',
|
||||
'./node_modules/node_modules/react-native-cookies/index.js',
|
||||
'./node_modules/node_modules/react-native-device-info/deviceinfo.js',
|
||||
'./node_modules/node_modules/react-native-device-info/src/index.ts',
|
||||
'./node_modules/node_modules/react-native-device-info/src/internal/asyncHookWrappers.ts',
|
||||
'./node_modules/node_modules/react-native-device-info/src/internal/devicesWithNotch.ts',
|
||||
'./node_modules/node_modules/react-native-device-info/src/internal/nativeInterface.ts',
|
||||
'./node_modules/node_modules/react-native-gesture-handler/GestureButtons.js',
|
||||
'./node_modules/node_modules/react-native-gesture-handler/GestureComponents.js',
|
||||
'./node_modules/node_modules/react-native-gesture-handler/GestureHandler.js',
|
||||
'./node_modules/node_modules/react-native-gesture-handler/GestureHandlerButton.js',
|
||||
'./node_modules/node_modules/react-native-gesture-handler/GestureHandlerPropTypes.js',
|
||||
|
|
@ -519,13 +510,14 @@ module.exports = [
|
|||
'./node_modules/node_modules/react-native-gesture-handler/NativeViewGestureHandler.js',
|
||||
'./node_modules/node_modules/react-native-gesture-handler/PlatformConstants.js',
|
||||
'./node_modules/node_modules/react-native-gesture-handler/RNGestureHandlerModule.js',
|
||||
'./node_modules/node_modules/react-native-gesture-handler/State.js',
|
||||
'./node_modules/node_modules/react-native-gesture-handler/createHandler.js',
|
||||
'./node_modules/node_modules/react-native-gesture-handler/createNativeWrapper.js',
|
||||
'./node_modules/node_modules/react-native-gesture-handler/gestureHandlerRootHOC.js',
|
||||
'./node_modules/node_modules/react-native-gesture-handler/index.js',
|
||||
'./node_modules/node_modules/react-native-haptic-feedback/index.js',
|
||||
'./node_modules/node_modules/react-native-keychain/index.js',
|
||||
'./node_modules/node_modules/react-native-localize/lib/commonjs/index.js',
|
||||
'./node_modules/node_modules/react-native-localize/lib/commonjs/module.js',
|
||||
'./node_modules/node_modules/react-native-mmkv-storage/index.js',
|
||||
'./node_modules/node_modules/react-native-mmkv-storage/src/api.js',
|
||||
'./node_modules/node_modules/react-native-mmkv-storage/src/encryption.js',
|
||||
|
|
@ -734,7 +726,6 @@ module.exports = [
|
|||
'./node_modules/node_modules/react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore.js',
|
||||
'./node_modules/node_modules/react-native/Libraries/ReactPrivate/ReactNativePrivateInterface.js',
|
||||
'./node_modules/node_modules/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js',
|
||||
'./node_modules/node_modules/react-native/Libraries/Renderer/shims/NativeMethodsMixin.js',
|
||||
'./node_modules/node_modules/react-native/Libraries/Renderer/shims/ReactNative.js',
|
||||
'./node_modules/node_modules/react-native/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js',
|
||||
'./node_modules/node_modules/react-native/Libraries/Renderer/shims/createReactNativeComponentClass.js',
|
||||
|
|
@ -751,6 +742,7 @@ module.exports = [
|
|||
'./node_modules/node_modules/react-native/Libraries/TurboModule/TurboModuleRegistry.js',
|
||||
'./node_modules/node_modules/react-native/Libraries/UTFSequence.js',
|
||||
'./node_modules/node_modules/react-native/Libraries/Utilities/BackHandler.android.js',
|
||||
'./node_modules/node_modules/react-native/Libraries/Utilities/DeviceInfo.js',
|
||||
'./node_modules/node_modules/react-native/Libraries/Utilities/Dimensions.js',
|
||||
'./node_modules/node_modules/react-native/Libraries/Utilities/GlobalPerformanceLogger.js',
|
||||
'./node_modules/node_modules/react-native/Libraries/Utilities/HMRClient.js',
|
||||
|
|
@ -898,18 +890,16 @@ module.exports = [
|
|||
'./node_modules/node_modules/semver/ranges/min-satisfying.js',
|
||||
'./node_modules/node_modules/semver/ranges/min-version.js',
|
||||
'./node_modules/node_modules/semver/ranges/outside.js',
|
||||
'./node_modules/node_modules/semver/ranges/simplify.js',
|
||||
'./node_modules/node_modules/semver/ranges/to-comparators.js',
|
||||
'./node_modules/node_modules/semver/ranges/valid.js',
|
||||
'./node_modules/node_modules/serialize-error/index.js',
|
||||
'./node_modules/node_modules/shallow-equals/index.js',
|
||||
'./node_modules/node_modules/simple-swizzle/index.js',
|
||||
'./node_modules/node_modules/stacktrace-parser/dist/stack-trace-parser.cjs.js',
|
||||
'./node_modules/node_modules/simple-swizzle/node_modules/is-arrayish/index.js',
|
||||
'./node_modules/node_modules/symbol-observable/lib/index.js',
|
||||
'./node_modules/node_modules/symbol-observable/lib/ponyfill.js',
|
||||
'./node_modules/node_modules/url-parse/index.js',
|
||||
'./node_modules/node_modules/util/support/isBufferBrowser.js',
|
||||
'./node_modules/node_modules/util/support/types.js',
|
||||
'./node_modules/node_modules/util/util.js',
|
||||
'./node_modules/share_extension/android/actions/index.js',
|
||||
'./node_modules/share_extension/android/index.js',
|
||||
];
|
||||
39
patches/@react-native-community+cookies+2.0.9.patch
Normal file
39
patches/@react-native-community+cookies+2.0.9.patch
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
diff --git a/node_modules/@react-native-community/cookies/ios/RNCookieManagerIOS/RNCookieManagerIOS.m b/node_modules/@react-native-community/cookies/ios/RNCookieManagerIOS/RNCookieManagerIOS.m
|
||||
index 9cdc74d..5477405 100644
|
||||
--- a/node_modules/@react-native-community/cookies/ios/RNCookieManagerIOS/RNCookieManagerIOS.m
|
||||
+++ b/node_modules/@react-native-community/cookies/ios/RNCookieManagerIOS/RNCookieManagerIOS.m
|
||||
@@ -139,7 +139,8 @@ + (BOOL)requiresMainQueueSetup
|
||||
[cookieStore getAllCookies:^(NSArray<NSHTTPCookie *> *allCookies) {
|
||||
NSMutableDictionary *cookies = [NSMutableDictionary dictionary];
|
||||
for (NSHTTPCookie *cookie in allCookies) {
|
||||
- if ([topLevelDomain containsString:cookie.domain]) {
|
||||
+ NSString *domainWithDot = [NSString stringWithFormat:@".%@", cookie.domain];
|
||||
+ if([cookie.domain containsString:topLevelDomain] || [domainWithDot containsString:topLevelDomain]) {
|
||||
[cookies setObject:[self createCookieData:cookie] forKey:cookie.name];
|
||||
}
|
||||
}
|
||||
@@ -185,6 +186,8 @@ + (BOOL)requiresMainQueueSetup
|
||||
}
|
||||
resolve(nil);
|
||||
}
|
||||
+
|
||||
+ [self deleteBinaryCookiesAndWebsiteData];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(clearByName:(NSString *) name
|
||||
@@ -244,4 +247,15 @@ -(NSDictionary *)createCookieData:(NSHTTPCookie *)cookie
|
||||
return cookieData;
|
||||
}
|
||||
|
||||
+-(void) deleteBinaryCookiesAndWebsiteData {
|
||||
+ NSString *libraryPath = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)[0];
|
||||
+ NSString *cookiesPath = [libraryPath stringByAppendingString:@"/Cookies/Cookies.binarycookies"];
|
||||
+ NSString *dataPath = [libraryPath stringByAppendingString:@"/WebKit/WebsiteData"];
|
||||
+
|
||||
+ NSError *error;
|
||||
+ NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
+ [fileManager removeItemAtPath:cookiesPath error:&error];
|
||||
+ [fileManager removeItemAtPath:dataPath error:&error];
|
||||
+}
|
||||
+
|
||||
@end
|
||||
13
patches/moment-timezone+0.5.29.patch
Normal file
13
patches/moment-timezone+0.5.29.patch
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
diff --git a/node_modules/moment-timezone/index.d.ts b/node_modules/moment-timezone/index.d.ts
|
||||
index 8cb684d..3a1d563 100644
|
||||
--- a/node_modules/moment-timezone/index.d.ts
|
||||
+++ b/node_modules/moment-timezone/index.d.ts
|
||||
@@ -66,6 +66,8 @@ declare module 'moment' {
|
||||
|
||||
/** Parse an offset for a timestamp constructed from Date.UTC in that zone. */
|
||||
parse(timestamp: number): number;
|
||||
+
|
||||
+ utcOffset(timestamp: number): number;
|
||||
}
|
||||
|
||||
/** Return a timezone by name or null if timezone by that name is not loaded. */
|
||||
28
patches/react-native-button+3.0.1.patch
Normal file
28
patches/react-native-button+3.0.1.patch
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
diff --git a/node_modules/react-native-button/Button.js b/node_modules/react-native-button/Button.js
|
||||
index b248176..2ee35d5 100644
|
||||
--- a/node_modules/react-native-button/Button.js
|
||||
+++ b/node_modules/react-native-button/Button.js
|
||||
@@ -71,7 +71,6 @@ export default class Button extends Component {
|
||||
}
|
||||
|
||||
return (
|
||||
- <View style={containerStyle}>
|
||||
<TouchableNativeFeedback
|
||||
{...touchableProps}
|
||||
style={{flex: 1}}
|
||||
@@ -79,11 +78,12 @@ export default class Button extends Component {
|
||||
accessibilityLabel={this.props.accessibilityLabel}
|
||||
accessibilityRole="button"
|
||||
background={background}>
|
||||
- <View style={{padding: padding}}>
|
||||
- {this._renderGroupedChildren()}
|
||||
+ <View style={containerStyle}>
|
||||
+ <View style={{padding: padding}}>
|
||||
+ {this._renderGroupedChildren()}
|
||||
+ </View>
|
||||
</View>
|
||||
</TouchableNativeFeedback>
|
||||
- </View>
|
||||
);
|
||||
}
|
||||
}
|
||||
17
patches/react-native-device-info+5.5.7.patch
Normal file
17
patches/react-native-device-info+5.5.7.patch
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
diff --git a/node_modules/react-native-device-info/android/src/main/java/com/learnium/RNDeviceInfo/resolver/DeviceTypeResolver.java b/node_modules/react-native-device-info/android/src/main/java/com/learnium/RNDeviceInfo/resolver/DeviceTypeResolver.java
|
||||
index a8e9b0c..2fac079 100644
|
||||
--- a/node_modules/react-native-device-info/android/src/main/java/com/learnium/RNDeviceInfo/resolver/DeviceTypeResolver.java
|
||||
+++ b/node_modules/react-native-device-info/android/src/main/java/com/learnium/RNDeviceInfo/resolver/DeviceTypeResolver.java
|
||||
@@ -80,10 +80,10 @@ public class DeviceTypeResolver {
|
||||
double heightInches = metrics.heightPixels / (double) metrics.ydpi;
|
||||
double diagonalSizeInches = Math.sqrt(Math.pow(widthInches, 2) + Math.pow(heightInches, 2));
|
||||
|
||||
- if (diagonalSizeInches >= 3.0 && diagonalSizeInches <= 6.9) {
|
||||
+ if (diagonalSizeInches >= 3.0 && diagonalSizeInches <= 7.9) {
|
||||
// Devices in a sane range for phones are considered to be Handsets.
|
||||
return DeviceType.HANDSET;
|
||||
- } else if (diagonalSizeInches > 6.9 && diagonalSizeInches <= 18.0) {
|
||||
+ } else if (diagonalSizeInches > 7.9 && diagonalSizeInches <= 18.0) {
|
||||
// Devices larger than handset and in a sane range for tablets are tablets.
|
||||
return DeviceType.TABLET;
|
||||
} else {
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
diff --git a/node_modules/react-native-elements/src/searchbar/SearchBar-android.js b/node_modules/react-native-elements/src/searchbar/SearchBar-android.js
|
||||
index eeaeb81..93f58de 100644
|
||||
index f44866a..76406c2 100644
|
||||
--- a/node_modules/react-native-elements/src/searchbar/SearchBar-android.js
|
||||
+++ b/node_modules/react-native-elements/src/searchbar/SearchBar-android.js
|
||||
@@ -78,6 +78,12 @@ class SearchBar extends Component {
|
||||
|
|
@ -16,7 +16,7 @@ index eeaeb81..93f58de 100644
|
|||
const {
|
||||
clearIcon,
|
||||
diff --git a/node_modules/react-native-elements/src/searchbar/SearchBar-ios.js b/node_modules/react-native-elements/src/searchbar/SearchBar-ios.js
|
||||
index 41ef6be..dbf727b 100644
|
||||
index 32a28d5..d43e9bf 100644
|
||||
--- a/node_modules/react-native-elements/src/searchbar/SearchBar-ios.js
|
||||
+++ b/node_modules/react-native-elements/src/searchbar/SearchBar-ios.js
|
||||
@@ -41,6 +41,12 @@ class SearchBar extends Component {
|
||||
|
|
@ -32,7 +32,7 @@ index 41ef6be..dbf727b 100644
|
|||
focus = () => {
|
||||
this.input.focus();
|
||||
};
|
||||
@@ -259,7 +265,6 @@ const styles = StyleSheet.create({
|
||||
@@ -260,7 +266,6 @@ const styles = StyleSheet.create({
|
||||
paddingBottom: 13,
|
||||
paddingTop: 13,
|
||||
flexDirection: 'row',
|
||||
|
|
@ -40,7 +40,7 @@ index 41ef6be..dbf727b 100644
|
|||
alignItems: 'center',
|
||||
},
|
||||
input: {
|
||||
@@ -270,7 +275,7 @@ const styles = StyleSheet.create({
|
||||
@@ -271,7 +276,7 @@ const styles = StyleSheet.create({
|
||||
borderBottomWidth: 0,
|
||||
backgroundColor: '#dcdce1',
|
||||
borderRadius: 9,
|
||||
|
|
@ -1,27 +1,8 @@
|
|||
diff --git a/node_modules/react-native-keyboard-tracking-view/lib/KeyboardTrackingViewManager.h b/node_modules/react-native-keyboard-tracking-view/lib/KeyboardTrackingViewManager.h
|
||||
index 0d9600e..03bd962 100644
|
||||
--- a/node_modules/react-native-keyboard-tracking-view/lib/KeyboardTrackingViewManager.h
|
||||
+++ b/node_modules/react-native-keyboard-tracking-view/lib/KeyboardTrackingViewManager.h
|
||||
@@ -11,4 +11,5 @@
|
||||
#import <React/RCTBridgeModule.h>
|
||||
|
||||
@interface KeyboardTrackingViewManager : RCTViewManager
|
||||
+
|
||||
@end
|
||||
diff --git a/node_modules/react-native-keyboard-tracking-view/lib/KeyboardTrackingViewManager.m b/node_modules/react-native-keyboard-tracking-view/lib/KeyboardTrackingViewManager.m
|
||||
index 800bd35..c215a8d 100644
|
||||
index 1333a10..86d3678 100644
|
||||
--- a/node_modules/react-native-keyboard-tracking-view/lib/KeyboardTrackingViewManager.m
|
||||
+++ b/node_modules/react-native-keyboard-tracking-view/lib/KeyboardTrackingViewManager.m
|
||||
@@ -6,6 +6,8 @@
|
||||
// Copyright © 2016 Wix.com All rights reserved.
|
||||
//
|
||||
|
||||
+#import <WebKit/WebKit.h>
|
||||
+
|
||||
#import "KeyboardTrackingViewManager.h"
|
||||
#import "ObservingInputAccessoryView.h"
|
||||
#import "UIResponder+FirstResponder.h"
|
||||
@@ -22,7 +24,7 @@
|
||||
@@ -23,7 +23,7 @@
|
||||
NSUInteger const kInputViewKey = 101010;
|
||||
NSUInteger const kMaxDeferedInitializeAccessoryViews = 15;
|
||||
NSInteger const kTrackingViewNotFoundErrorCode = 1;
|
||||
|
|
@ -30,7 +11,7 @@ index 800bd35..c215a8d 100644
|
|||
|
||||
typedef NS_ENUM(NSUInteger, KeyboardTrackingScrollBehavior) {
|
||||
KeyboardTrackingScrollBehaviorNone,
|
||||
@@ -39,6 +41,7 @@ @interface KeyboardTrackingView : UIView
|
||||
@@ -40,6 +40,7 @@ @interface KeyboardTrackingView : UIView
|
||||
CGFloat _bottomViewHeight;
|
||||
}
|
||||
|
||||
|
|
@ -38,21 +19,21 @@ index 800bd35..c215a8d 100644
|
|||
@property (nonatomic, strong) UIScrollView *scrollViewToManage;
|
||||
@property (nonatomic) BOOL scrollIsInverted;
|
||||
@property (nonatomic) BOOL revealKeyboardInteractive;
|
||||
@@ -51,6 +54,13 @@ @interface KeyboardTrackingView : UIView
|
||||
@property (nonatomic) BOOL addBottomView;
|
||||
@@ -53,6 +54,13 @@ @interface KeyboardTrackingView : UIView
|
||||
@property (nonatomic) BOOL scrollToFocusedInput;
|
||||
@property (nonatomic) BOOL allowHitsOutsideBounds;
|
||||
|
||||
+@property (nonatomic) BOOL normalList;
|
||||
+@property (nonatomic) NSString* scrollViewNativeID;
|
||||
+@property (nonatomic) CGFloat initialOffsetY;
|
||||
+@property (nonatomic) BOOL initialOffsetIsSet;
|
||||
+
|
||||
+@property (nonatomic, strong) UIView *accessoriesContainer;
|
||||
+@property (nonatomic) NSString* accessoriesContainerID;
|
||||
|
||||
+
|
||||
@end
|
||||
|
||||
@@ -69,12 +79,17 @@ -(instancetype)init
|
||||
@interface KeyboardTrackingView () <ObservingInputAccessoryViewDelegate, UIScrollViewDelegate>
|
||||
@@ -70,12 +78,17 @@ -(instancetype)init
|
||||
[self addObserver:self forKeyPath:@"bounds" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:NULL];
|
||||
_inputViewsMap = [NSMapTable weakToWeakObjectsMapTable];
|
||||
_deferedInitializeAccessoryViewsCount = 0;
|
||||
|
|
@ -60,7 +41,7 @@ index 800bd35..c215a8d 100644
|
|||
|
||||
_observingInputAccessoryView = [ObservingInputAccessoryView new];
|
||||
_observingInputAccessoryView.delegate = self;
|
||||
|
||||
|
||||
+ _initialOffsetY = 0;
|
||||
+ _initialOffsetIsSet = NO;
|
||||
+
|
||||
|
|
@ -70,13 +51,7 @@ index 800bd35..c215a8d 100644
|
|||
|
||||
_bottomViewHeight = kBottomViewHeight;
|
||||
|
||||
@@ -128,12 +143,12 @@ - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
|
||||
return subview;
|
||||
}
|
||||
|
||||
--(void)_swizzleWebViewInputAccessory:(UIWebView*)webview
|
||||
+-(void)_swizzleWebViewInputAccessory:(WKWebView*)webview
|
||||
{
|
||||
@@ -134,7 +147,7 @@ -(void)_swizzleWebViewInputAccessory:(WKWebView*)webview
|
||||
UIView* subview;
|
||||
for (UIView* view in webview.scrollView.subviews)
|
||||
{
|
||||
|
|
@ -85,7 +60,7 @@ index 800bd35..c215a8d 100644
|
|||
{
|
||||
subview = view;
|
||||
}
|
||||
@@ -166,33 +181,32 @@ -(void)layoutSubviews
|
||||
@@ -167,33 +180,32 @@ -(void)layoutSubviews
|
||||
- (void)initializeAccessoryViewsAndHandleInsets
|
||||
{
|
||||
NSArray<UIView*>* allSubviews = [self getBreadthFirstSubviewsForView:[self getRootView]];
|
||||
|
|
@ -96,27 +71,27 @@ index 800bd35..c215a8d 100644
|
|||
+ if(subview.nativeID) {
|
||||
+ NSLog(@"self.accessoriesContainerID %@ %@", self.accessoriesContainerID, subview.nativeID);
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ if (subview.nativeID && [subview.nativeID isEqualToString:self.accessoriesContainerID]) {
|
||||
+ NSLog(@"SuperView ID: %@", subview.nativeID);
|
||||
+ _accessoriesContainer = subview;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
if(_manageScrollView)
|
||||
{
|
||||
if(_scrollViewToManage == nil)
|
||||
{
|
||||
- if(_requiresSameParentToManageScrollView && [subview isKindOfClass:[RCTScrollView class]] && subview.superview == self.superview)
|
||||
+ if([subview isKindOfClass:[RCTScrollView class]])
|
||||
{
|
||||
- {
|
||||
- _scrollViewToManage = ((RCTScrollView*)subview).scrollView;
|
||||
- }
|
||||
- else if(!_requiresSameParentToManageScrollView && [subview isKindOfClass:[UIScrollView class]])
|
||||
- {
|
||||
+ if([subview isKindOfClass:[RCTScrollView class]])
|
||||
{
|
||||
- _scrollViewToManage = (UIScrollView*)subview;
|
||||
- }
|
||||
+ RCTScrollView *scrollView = (RCTScrollView*)subview;
|
||||
|
||||
|
||||
- if(_scrollViewToManage != nil)
|
||||
- {
|
||||
- _scrollIsInverted = CGAffineTransformEqualToTransform(_scrollViewToManage.superview.transform, CGAffineTransformMakeScale(1, -1));
|
||||
|
|
@ -134,15 +109,7 @@ index 800bd35..c215a8d 100644
|
|||
}
|
||||
|
||||
if ([subview isKindOfClass:NSClassFromString(@"RCTTextField")])
|
||||
@@ -235,13 +249,13 @@ - (void)initializeAccessoryViewsAndHandleInsets
|
||||
{
|
||||
[self setupTextView:(UITextView*)subview];
|
||||
}
|
||||
- else if ([subview isKindOfClass:[UIWebView class]])
|
||||
+ else if ([subview isKindOfClass:[WKWebView class]])
|
||||
{
|
||||
- [self _swizzleWebViewInputAccessory:(UIWebView*)subview];
|
||||
+ [self _swizzleWebViewInputAccessory:(WKWebView*)subview];
|
||||
@@ -242,7 +254,7 @@ - (void)initializeAccessoryViewsAndHandleInsets
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -151,7 +118,7 @@ index 800bd35..c215a8d 100644
|
|||
{
|
||||
if(scrollView.scrollView == _scrollViewToManage)
|
||||
{
|
||||
@@ -266,6 +280,21 @@ - (void)initializeAccessoryViewsAndHandleInsets
|
||||
@@ -267,6 +279,21 @@ - (void)initializeAccessoryViewsAndHandleInsets
|
||||
[self addBottomViewIfNecessary];
|
||||
}
|
||||
|
||||
|
|
@ -173,7 +140,7 @@ index 800bd35..c215a8d 100644
|
|||
- (void)setupTextView:(UITextView*)textView
|
||||
{
|
||||
if (textView != nil)
|
||||
@@ -342,7 +371,7 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N
|
||||
@@ -343,7 +370,7 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N
|
||||
|
||||
- (void)observingInputAccessoryViewKeyboardWillDisappear:(ObservingInputAccessoryView *)observingInputAccessoryView
|
||||
{
|
||||
|
|
@ -182,7 +149,7 @@ index 800bd35..c215a8d 100644
|
|||
[self updateBottomViewFrame];
|
||||
}
|
||||
|
||||
@@ -387,32 +416,43 @@ - (void)_updateScrollViewInsets
|
||||
@@ -388,32 +415,42 @@ - (void)_updateScrollViewInsets
|
||||
{
|
||||
if(self.scrollViewToManage != nil)
|
||||
{
|
||||
|
|
@ -190,7 +157,7 @@ index 800bd35..c215a8d 100644
|
|||
+ self.initialOffsetY = self.scrollViewToManage.contentOffset.y;
|
||||
+ _initialOffsetIsSet = YES;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ if (_observingInputAccessoryView.keyboardState != KeyboardStateWillHide && _observingInputAccessoryView.keyboardState != KeyboardStateHidden) {
|
||||
+ [self.scrollViewToManage setContentOffset:CGPointMake(self.scrollViewToManage.contentOffset.x, self.initialOffsetY) animated:NO];
|
||||
+ }
|
||||
|
|
@ -214,7 +181,6 @@ index 800bd35..c215a8d 100644
|
|||
- insets.bottom = bottomInset;
|
||||
+ insets.bottom = keyboardHeight;
|
||||
}
|
||||
+
|
||||
self.scrollViewToManage.contentInset = insets;
|
||||
|
||||
if(self.scrollBehavior == KeyboardTrackingScrollBehaviorScrollToBottomInvertedOnly && _scrollIsInverted)
|
||||
|
|
@ -231,10 +197,10 @@ index 800bd35..c215a8d 100644
|
|||
}
|
||||
}
|
||||
else if(self.scrollBehavior == KeyboardTrackingScrollBehaviorFixedOffset && !self.isDraggingScrollView)
|
||||
@@ -421,16 +461,16 @@ - (void)_updateScrollViewInsets
|
||||
@@ -422,16 +459,15 @@ - (void)_updateScrollViewInsets
|
||||
self.scrollViewToManage.contentOffset = CGPointMake(originalOffset.x, originalOffset.y + insetsDiff);
|
||||
}
|
||||
|
||||
|
||||
- insets = self.scrollViewToManage.contentInset;
|
||||
- if(self.scrollIsInverted)
|
||||
- {
|
||||
|
|
@ -247,30 +213,24 @@ index 800bd35..c215a8d 100644
|
|||
+ CGRect frame = CGRectMake(self.scrollViewToManage.frame.origin.x, positionY,
|
||||
+ self.scrollViewToManage.frame.size.width, self.scrollViewToManage.frame.size.height);
|
||||
+ self.scrollViewToManage.frame = frame;
|
||||
+
|
||||
+
|
||||
+ if (self.accessoriesContainer) {
|
||||
+ self.accessoriesContainer.bounds = CGRectMake(self.accessoriesContainer.bounds.origin.x, positionY,
|
||||
+ self.accessoriesContainer.bounds.size.width, self.accessoriesContainer.bounds.size.height);
|
||||
}
|
||||
- self.scrollViewToManage.scrollIndicatorInsets = insets;
|
||||
+
|
||||
}
|
||||
}
|
||||
|
||||
@@ -447,11 +487,9 @@ -(void)addBottomViewIfNecessary
|
||||
@@ -448,7 +484,6 @@ -(void)addBottomViewIfNecessary
|
||||
if (self.addBottomView && _bottomView == nil)
|
||||
{
|
||||
_bottomView = [UIView new];
|
||||
- _bottomView.backgroundColor = [UIColor whiteColor];
|
||||
[self addSubview:_bottomView];
|
||||
[self updateBottomViewFrame];
|
||||
- }
|
||||
- else if (!self.addBottomView && _bottomView != nil)
|
||||
+ } else if (!self.addBottomView && _bottomView != nil)
|
||||
{
|
||||
[_bottomView removeFromSuperview];
|
||||
_bottomView = nil;
|
||||
@@ -466,6 +504,12 @@ -(void)updateBottomViewFrame
|
||||
}
|
||||
@@ -467,6 +502,12 @@ -(void)updateBottomViewFrame
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -283,16 +243,7 @@ index 800bd35..c215a8d 100644
|
|||
#pragma mark - safe area
|
||||
|
||||
-(void)safeAreaInsetsDidChange
|
||||
@@ -483,7 +527,7 @@ -(CGFloat)getBottomSafeArea
|
||||
CGFloat bottomSafeArea = 0;
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_10_3
|
||||
if (@available(iOS 11.0, *)) {
|
||||
- bottomSafeArea = self.superview ? self.superview.safeAreaInsets.bottom : self.safeAreaInsets.bottom;
|
||||
+ bottomSafeArea = self.superview ? self.superview.safeAreaInsets.bottom : self.safeAreaInsets.bottom;
|
||||
}
|
||||
#endif
|
||||
return bottomSafeArea;
|
||||
@@ -509,7 +553,7 @@ -(void)updateTransformAndInsets
|
||||
@@ -510,7 +551,7 @@ -(void)updateTransformAndInsets
|
||||
CGFloat accessoryTranslation = MIN(-bottomSafeArea, -_observingInputAccessoryView.keyboardHeight);
|
||||
|
||||
if (_observingInputAccessoryView.keyboardHeight <= bottomSafeArea) {
|
||||
|
|
@ -301,7 +252,7 @@ index 800bd35..c215a8d 100644
|
|||
} else if (_observingInputAccessoryView.keyboardState != KeyboardStateWillHide) {
|
||||
_bottomViewHeight = 0;
|
||||
}
|
||||
@@ -553,6 +597,14 @@ - (void) observingInputAccessoryViewKeyboardWillAppear:(ObservingInputAccessoryV
|
||||
@@ -554,6 +595,14 @@ - (void) observingInputAccessoryViewKeyboardWillAppear:(ObservingInputAccessoryV
|
||||
[self performScrollToFocusedInput];
|
||||
}
|
||||
|
||||
|
|
@ -316,7 +267,7 @@ index 800bd35..c215a8d 100644
|
|||
#pragma mark - UIScrollViewDelegate methods
|
||||
|
||||
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
|
||||
@@ -581,6 +633,8 @@ - (void)scrollViewDidScroll:(UIScrollView *)scrollView
|
||||
@@ -582,6 +631,8 @@ - (void)scrollViewDidScroll:(UIScrollView *)scrollView
|
||||
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
|
||||
{
|
||||
self.isDraggingScrollView = YES;
|
||||
|
|
@ -325,7 +276,7 @@ index 800bd35..c215a8d 100644
|
|||
}
|
||||
|
||||
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
|
||||
@@ -591,6 +645,15 @@ - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoi
|
||||
@@ -592,6 +643,15 @@ - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoi
|
||||
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
|
||||
{
|
||||
self.isDraggingScrollView = NO;
|
||||
|
|
@ -341,7 +292,7 @@ index 800bd35..c215a8d 100644
|
|||
}
|
||||
|
||||
- (CGFloat)getKeyboardHeight
|
||||
@@ -633,6 +696,12 @@ @implementation KeyboardTrackingViewManager
|
||||
@@ -634,6 +694,12 @@ @implementation KeyboardTrackingViewManager
|
||||
RCT_REMAP_VIEW_PROPERTY(addBottomView, addBottomView, BOOL)
|
||||
RCT_REMAP_VIEW_PROPERTY(scrollToFocusedInput, scrollToFocusedInput, BOOL)
|
||||
RCT_REMAP_VIEW_PROPERTY(allowHitsOutsideBounds, allowHitsOutsideBounds, BOOL)
|
||||
|
|
@ -354,8 +305,8 @@ index 800bd35..c215a8d 100644
|
|||
|
||||
+ (BOOL)requiresMainQueueSetup
|
||||
{
|
||||
@@ -687,6 +756,20 @@ - (UIView *)view
|
||||
}];
|
||||
@@ -654,6 +720,20 @@ - (UIView *)view
|
||||
return [[KeyboardTrackingView alloc] init];
|
||||
}
|
||||
|
||||
+RCT_EXPORT_METHOD(resetScrollView:(nonnull NSNumber *)reactTag scrollViewNativeID:(NSString*)scrollViewNativeID) {
|
||||
|
|
@ -372,9 +323,9 @@ index 800bd35..c215a8d 100644
|
|||
+ }];
|
||||
+}
|
||||
+
|
||||
#pragma mark - helper methods
|
||||
|
||||
-(void)rejectPromise:(RCTPromiseRejectBlock)reject withErrorMessage:(NSString*)errorMessage errorCode:(NSInteger)errorCode
|
||||
RCT_EXPORT_METHOD(getNativeProps:(nonnull NSNumber *)reactTag resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
|
||||
{
|
||||
[self.bridge.uiManager addUIBlock:
|
||||
diff --git a/node_modules/react-native-keyboard-tracking-view/lib/ObservingInputAccessoryView.h b/node_modules/react-native-keyboard-tracking-view/lib/ObservingInputAccessoryView.h
|
||||
index 9b242e8..b500db1 100644
|
||||
--- a/node_modules/react-native-keyboard-tracking-view/lib/ObservingInputAccessoryView.h
|
||||
|
|
@ -388,21 +339,21 @@ index 9b242e8..b500db1 100644
|
|||
@end
|
||||
|
||||
diff --git a/node_modules/react-native-keyboard-tracking-view/lib/ObservingInputAccessoryView.m b/node_modules/react-native-keyboard-tracking-view/lib/ObservingInputAccessoryView.m
|
||||
index e472679..1e62c61 100644
|
||||
index e472679..dbc5c5e 100644
|
||||
--- a/node_modules/react-native-keyboard-tracking-view/lib/ObservingInputAccessoryView.m
|
||||
+++ b/node_modules/react-native-keyboard-tracking-view/lib/ObservingInputAccessoryView.m
|
||||
@@ -130,6 +130,11 @@ - (void)_keyboardDidShowNotification:(NSNotification*)notification
|
||||
_keyboardState = KeyboardStateShown;
|
||||
|
||||
[self invalidateIntrinsicContentSize];
|
||||
+
|
||||
@@ -123,6 +123,11 @@ - (void)_keyboardWillShowNotification:(NSNotification*)notification
|
||||
{
|
||||
[_delegate observingInputAccessoryViewKeyboardWillAppear:self keyboardDelta:_keyboardHeight - _previousKeyboardHeight];
|
||||
}
|
||||
+
|
||||
+ if([_delegate respondsToSelector:@selector(observingInputAccessoryViewKeyboardDidAppear:)])
|
||||
+ {
|
||||
+ [_delegate observingInputAccessoryViewKeyboardDidAppear:self];
|
||||
+ }
|
||||
}
|
||||
|
||||
- (void)_keyboardWillHideNotification:(NSNotification*)notification
|
||||
- (void)_keyboardDidShowNotification:(NSNotification*)notification
|
||||
diff --git a/node_modules/react-native-keyboard-tracking-view/src/KeyboardTrackingView.android.js b/node_modules/react-native-keyboard-tracking-view/src/KeyboardTrackingView.android.js
|
||||
index af15edf..3ba0a3a 100644
|
||||
--- a/node_modules/react-native-keyboard-tracking-view/src/KeyboardTrackingView.android.js
|
||||
|
|
@ -415,7 +366,7 @@ index af15edf..3ba0a3a 100644
|
|||
scrollToStart() {}
|
||||
}
|
||||
diff --git a/node_modules/react-native-keyboard-tracking-view/src/KeyboardTrackingView.ios.js b/node_modules/react-native-keyboard-tracking-view/src/KeyboardTrackingView.ios.js
|
||||
index 5e2c207..e6099f3 100644
|
||||
index 5e2c207..727017c 100644
|
||||
--- a/node_modules/react-native-keyboard-tracking-view/src/KeyboardTrackingView.ios.js
|
||||
+++ b/node_modules/react-native-keyboard-tracking-view/src/KeyboardTrackingView.ios.js
|
||||
@@ -25,6 +25,12 @@ export default class KeyboardTrackingView extends PureComponent {
|
||||
|
|
@ -423,9 +374,9 @@ index 5e2c207..e6099f3 100644
|
|||
}
|
||||
|
||||
+ resetScrollView(scrollViewNativeID) {
|
||||
+ if (this.ref && KeyboardTrackingViewManager && KeyboardTrackingViewManager.resetScrollView) {
|
||||
+ KeyboardTrackingViewManager.resetScrollView(ReactNative.findNodeHandle(this.ref), scrollViewNativeID);
|
||||
+ }
|
||||
+ if (this.ref && KeyboardTrackingViewManager && KeyboardTrackingViewManager.resetScrollView) {
|
||||
+ KeyboardTrackingViewManager.resetScrollView(ReactNative.findNodeHandle(this.ref), scrollViewNativeID);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
scrollToStart() {
|
||||
188
patches/react-native-webview+9.4.0.patch
Normal file
188
patches/react-native-webview+9.4.0.patch
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
diff --git a/node_modules/react-native-webview/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java b/node_modules/react-native-webview/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java
|
||||
index 1995d87..33bd83c 100644
|
||||
--- a/node_modules/react-native-webview/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java
|
||||
+++ b/node_modules/react-native-webview/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java
|
||||
@@ -2,8 +2,12 @@ package com.reactnativecommunity.webview;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.TargetApi;
|
||||
+import android.app.Activity;
|
||||
+import android.app.AlertDialog;
|
||||
import android.app.DownloadManager;
|
||||
+import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
+import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
@@ -15,6 +19,7 @@ import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.core.content.ContextCompat;
|
||||
+import android.text.InputType;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
@@ -25,7 +30,9 @@ import android.webkit.ConsoleMessage;
|
||||
import android.webkit.CookieManager;
|
||||
import android.webkit.DownloadListener;
|
||||
import android.webkit.GeolocationPermissions;
|
||||
+import android.webkit.HttpAuthHandler;
|
||||
import android.webkit.JavascriptInterface;
|
||||
+import android.widget.LinearLayout;
|
||||
import android.webkit.PermissionRequest;
|
||||
import android.webkit.URLUtil;
|
||||
import android.webkit.ValueCallback;
|
||||
@@ -35,6 +42,7 @@ import android.webkit.WebResourceResponse;
|
||||
import android.webkit.WebSettings;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
+import android.widget.EditText;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import com.facebook.react.views.scroll.ScrollEvent;
|
||||
@@ -720,6 +728,7 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
|
||||
|
||||
protected static class RNCWebViewClient extends WebViewClient {
|
||||
|
||||
+ protected Activity mCurrentActivity;
|
||||
protected boolean mLastLoadFailed = false;
|
||||
protected @Nullable
|
||||
ReadableArray mUrlPrefixesForDefaultIntent;
|
||||
@@ -729,6 +738,10 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
|
||||
ignoreErrFailedForThisURL = url;
|
||||
}
|
||||
|
||||
+ public void setCurrentActivity(Activity mCurrentActivity) {
|
||||
+ this.mCurrentActivity = mCurrentActivity;
|
||||
+ }
|
||||
+
|
||||
@Override
|
||||
public void onPageFinished(WebView webView, String url) {
|
||||
super.onPageFinished(webView, url);
|
||||
@@ -810,6 +823,49 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
|
||||
new TopLoadingErrorEvent(webView.getId(), eventData));
|
||||
}
|
||||
|
||||
+ @Override
|
||||
+ public void onReceivedHttpAuthRequest(WebView view,
|
||||
+ final HttpAuthHandler handler, String host, String realm)
|
||||
+ {
|
||||
+ if (this.mCurrentActivity != null) {
|
||||
+ final EditText usernameInput = new EditText(this.mCurrentActivity);
|
||||
+ usernameInput.setHint("Username");
|
||||
+
|
||||
+ final EditText passwordInput = new EditText(this.mCurrentActivity);
|
||||
+ passwordInput.setHint("Password");
|
||||
+ passwordInput.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
|
||||
+
|
||||
+ LinearLayout layout = new LinearLayout(this.mCurrentActivity);
|
||||
+ layout.setOrientation(LinearLayout.VERTICAL);
|
||||
+ layout.addView(usernameInput);
|
||||
+ layout.addView(passwordInput);
|
||||
+
|
||||
+ AlertDialog.Builder authDialog = new AlertDialog.Builder(this.mCurrentActivity)
|
||||
+ .setTitle("Authentication Challenge")
|
||||
+ .setMessage(host + " requires user name and password ")
|
||||
+ .setView(layout)
|
||||
+ .setCancelable(false)
|
||||
+ .setPositiveButton("OK", new DialogInterface.OnClickListener() {
|
||||
+ public void onClick(DialogInterface dialogInterface, int i) {
|
||||
+ handler.proceed(usernameInput.getText().toString(), passwordInput.getText().toString());
|
||||
+ dialogInterface.dismiss();
|
||||
+ }
|
||||
+ })
|
||||
+ .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
|
||||
+ public void onClick(DialogInterface dialogInterface, int i) {
|
||||
+ dialogInterface.dismiss();
|
||||
+ handler.cancel();
|
||||
+ }
|
||||
+ });
|
||||
+
|
||||
+ if (view != null) {
|
||||
+ authDialog.show();
|
||||
+ }
|
||||
+ } else {
|
||||
+ handler.cancel();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
@RequiresApi(api = Build.VERSION_CODES.M)
|
||||
@Override
|
||||
public void onReceivedHttpError(
|
||||
@@ -1010,6 +1066,7 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
|
||||
protected boolean sendContentSizeChangeEvents = false;
|
||||
private OnScrollDispatchHelper mOnScrollDispatchHelper;
|
||||
protected boolean hasScrollEvent = false;
|
||||
+ protected ReactContext reactContext;
|
||||
|
||||
/**
|
||||
* WebView must be created with an context of the current activity
|
||||
@@ -1019,6 +1076,7 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
|
||||
*/
|
||||
public RNCWebView(ThemedReactContext reactContext) {
|
||||
super(reactContext);
|
||||
+ this.reactContext = reactContext;
|
||||
}
|
||||
|
||||
public void setIgnoreErrFailedForThisURL(String url) {
|
||||
@@ -1069,6 +1127,9 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
|
||||
super.setWebViewClient(client);
|
||||
if (client instanceof RNCWebViewClient) {
|
||||
mRNCWebViewClient = (RNCWebViewClient) client;
|
||||
+ if (this.reactContext != null && this.reactContext.getCurrentActivity() != null && mRNCWebViewClient != null) {
|
||||
+ mRNCWebViewClient.setCurrentActivity(this.reactContext.getCurrentActivity());
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/node_modules/react-native-webview/apple/RNCWebView.m b/node_modules/react-native-webview/apple/RNCWebView.m
|
||||
index d2f9956..4b8d0fe 100644
|
||||
--- a/node_modules/react-native-webview/apple/RNCWebView.m
|
||||
+++ b/node_modules/react-native-webview/apple/RNCWebView.m
|
||||
@@ -737,7 +737,44 @@ - (void) webView:(WKWebView *)webView
|
||||
if (webView.URL != nil) {
|
||||
host = webView.URL.host;
|
||||
}
|
||||
- if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodClientCertificate) {
|
||||
+
|
||||
+ NSString *authenticationMethod = [[challenge protectionSpace] authenticationMethod];
|
||||
+
|
||||
+ if (authenticationMethod == NSURLAuthenticationMethodNTLM || authenticationMethod == NSURLAuthenticationMethodNegotiate) {
|
||||
+ NSString *title = @"Authentication Challenge";
|
||||
+ NSString *message = [NSString stringWithFormat:@"%@ requires user name and password", host];
|
||||
+ UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
|
||||
+ [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {
|
||||
+ textField.placeholder = @"User";
|
||||
+ }];
|
||||
+
|
||||
+ [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {
|
||||
+ textField.placeholder = @"Password";
|
||||
+ textField.secureTextEntry = YES;
|
||||
+ }];
|
||||
+
|
||||
+ [alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
|
||||
+ NSString *userName = ((UITextField *)alertController.textFields[0]).text;
|
||||
+ NSString *password = ((UITextField *)alertController.textFields[1]).text;
|
||||
+ NSURLCredential *credential = [[NSURLCredential alloc] initWithUser:userName password:password persistence:NSURLCredentialPersistenceNone];
|
||||
+
|
||||
+ completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
|
||||
+ }]];
|
||||
+
|
||||
+ [alertController addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
|
||||
+ completionHandler(NSURLSessionAuthChallengeUseCredential, nil);
|
||||
+ }]];
|
||||
+
|
||||
+ dispatch_async(dispatch_get_main_queue(), ^{
|
||||
+ UIViewController *rootVC = UIApplication.sharedApplication.delegate.window.rootViewController;
|
||||
+
|
||||
+ while (rootVC.presentedViewController != nil) {
|
||||
+ rootVC = rootVC.presentedViewController;
|
||||
+ }
|
||||
+ [rootVC presentViewController:alertController animated:YES completion:^{}];
|
||||
+ });
|
||||
+ return;
|
||||
+ } else if (authenticationMethod == NSURLAuthenticationMethodClientCertificate) {
|
||||
completionHandler(NSURLSessionAuthChallengeUseCredential, clientAuthenticationCredential);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1,27 +1,24 @@
|
|||
diff --git a/node_modules/react-native-youtube/RCTYouTubeStandalone.m b/node_modules/react-native-youtube/RCTYouTubeStandalone.m
|
||||
index fabd291..1e29586 100644
|
||||
index fabd291..45b322b 100644
|
||||
--- a/node_modules/react-native-youtube/RCTYouTubeStandalone.m
|
||||
+++ b/node_modules/react-native-youtube/RCTYouTubeStandalone.m
|
||||
@@ -5,6 +5,18 @@
|
||||
@@ -5,6 +5,15 @@
|
||||
#endif
|
||||
@import AVKit;
|
||||
|
||||
+@interface AVPlayerViewControllerRotation : AVPlayerViewController
|
||||
+
|
||||
+@end
|
||||
+
|
||||
+@implementation AVPlayerViewControllerRotation
|
||||
+
|
||||
+- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
|
||||
+ return UIInterfaceOrientationMaskAllButUpsideDown;
|
||||
+}
|
||||
+
|
||||
+@end
|
||||
+
|
||||
@implementation RCTYouTubeStandalone {
|
||||
RCTPromiseResolveBlock resolver;
|
||||
RCTPromiseRejectBlock rejecter;
|
||||
@@ -14,6 +26,7 @@ @implementation RCTYouTubeStandalone {
|
||||
@@ -14,6 +23,7 @@ @implementation RCTYouTubeStandalone {
|
||||
|
||||
RCT_REMAP_METHOD(playVideo,
|
||||
playVideoWithResolver:(NSString*)videoId
|
||||
|
|
@ -29,7 +26,7 @@ index fabd291..1e29586 100644
|
|||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject)
|
||||
{
|
||||
@@ -22,10 +35,10 @@ @implementation RCTYouTubeStandalone {
|
||||
@@ -22,10 +32,10 @@ @implementation RCTYouTubeStandalone {
|
||||
#else
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
UIViewController *root = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
|
||||
|
|
@ -42,7 +39,7 @@ index fabd291..1e29586 100644
|
|||
|
||||
[[XCDYouTubeClient defaultClient] getVideoWithIdentifier:videoId
|
||||
completionHandler:^(XCDYouTubeVideo * _Nullable video, NSError * _Nullable error) {
|
||||
@@ -38,10 +51,18 @@ @implementation RCTYouTubeStandalone {
|
||||
@@ -38,10 +48,18 @@ @implementation RCTYouTubeStandalone {
|
||||
streamURLs[@(XCDYouTubeVideoQualitySmall240)
|
||||
];
|
||||
|
||||
|
|
@ -51,27 +48,27 @@ index fabd291..1e29586 100644
|
|||
-
|
||||
- resolve(@"YouTubeStandaloneIOS player launched successfully");
|
||||
+ @try {
|
||||
+ CMTime initialPlaybackTime = CMTimeMakeWithSeconds([startTime doubleValue], 1);
|
||||
+ weakPlayerViewController.player = [AVPlayer playerWithURL:streamURL];
|
||||
+ [weakPlayerViewController.player seekToTime:initialPlaybackTime completionHandler: ^(BOOL finished) {
|
||||
+ [weakPlayerViewController.player play];
|
||||
+ resolve(@"YouTubeStandaloneIOS player launched successfully");
|
||||
+ }];
|
||||
+ }
|
||||
+ @catch (NSException *ex) {
|
||||
+ reject(@"error", ex.reason, nil);
|
||||
+ [root dismissViewControllerAnimated:YES completion:nil];
|
||||
+ }
|
||||
+ CMTime initialPlaybackTime = CMTimeMakeWithSeconds([startTime doubleValue], 1);
|
||||
+ weakPlayerViewController.player = [AVPlayer playerWithURL:streamURL];
|
||||
+ [weakPlayerViewController.player seekToTime:initialPlaybackTime completionHandler: ^(BOOL finished) {
|
||||
+ [weakPlayerViewController.player play];
|
||||
+ resolve(@"YouTubeStandaloneIOS player launched successfully");
|
||||
+ }];
|
||||
+ }
|
||||
+ @catch (NSException *ex) {
|
||||
+ reject(@"error", ex.reason, nil);
|
||||
+ [root dismissViewControllerAnimated:YES completion:nil];
|
||||
+ }
|
||||
} else {
|
||||
reject(@"error", error.localizedDescription, nil);
|
||||
[root dismissViewControllerAnimated:YES completion:nil];
|
||||
diff --git a/node_modules/react-native-youtube/YouTubeStandalone.ios.js b/node_modules/react-native-youtube/YouTubeStandalone.ios.js
|
||||
index b5e1b3c..f7c9999 100644
|
||||
index 0ee59c6..4a8294b 100644
|
||||
--- a/node_modules/react-native-youtube/YouTubeStandalone.ios.js
|
||||
+++ b/node_modules/react-native-youtube/YouTubeStandalone.ios.js
|
||||
@@ -5,4 +5,4 @@ const { YouTubeStandalone } = NativeModules;
|
||||
@@ -4,4 +4,4 @@ const { YouTubeStandalone } = NativeModules;
|
||||
|
||||
export const YouTubeStandaloneIOS = !YouTubeStandalone
|
||||
? null
|
||||
- : { playVideo: videoId => YouTubeStandalone.playVideo(videoId) };
|
||||
- : { playVideo: (videoId) => YouTubeStandalone.playVideo(videoId) };
|
||||
+ : { playVideo: (videoId, startTime) => YouTubeStandalone.playVideo(videoId, startTime) };
|
||||
|
|
@ -15,7 +15,7 @@ export function getTeamChannels(teamId) {
|
|||
const channelsInTeam = getChannelsNameMapInTeam(state, teamId);
|
||||
const redirectChannel = getChannelByName(channelsInTeam, getRedirectChannelNameForTeam(state, teamId));
|
||||
|
||||
return redirectChannel.id;
|
||||
return redirectChannel?.id;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
import React, {PureComponent} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {intlShape} from 'react-intl';
|
||||
import {NavigationActions} from 'react-navigation';
|
||||
import {CommonActions as NavigationActions} from '@react-navigation/native';
|
||||
import {
|
||||
ActivityIndicator,
|
||||
SectionList,
|
||||
|
|
@ -28,6 +28,7 @@ export default class ExtensionTeam extends PureComponent {
|
|||
navigation: PropTypes.object.isRequired,
|
||||
privateChannels: PropTypes.array,
|
||||
publicChannels: PropTypes.array,
|
||||
route: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
|
|
@ -40,10 +41,6 @@ export default class ExtensionTeam extends PureComponent {
|
|||
intl: intlShape,
|
||||
};
|
||||
|
||||
static navigationOptions = ({navigation}) => ({
|
||||
title: navigation.state.params.title,
|
||||
});
|
||||
|
||||
state = {
|
||||
sections: null,
|
||||
};
|
||||
|
|
@ -102,14 +99,14 @@ export default class ExtensionTeam extends PureComponent {
|
|||
};
|
||||
|
||||
handleSelectChannel = async (channel) => {
|
||||
const {state} = this.props.navigation;
|
||||
const backAction = NavigationActions.back();
|
||||
const {navigation, route} = this.props;
|
||||
const backAction = NavigationActions.goBack();
|
||||
|
||||
if (state.params && state.params.onSelectChannel) {
|
||||
state.params.onSelectChannel(channel.id);
|
||||
if (route?.params?.onSelectChannel) {
|
||||
route.params.onSelectChannel(channel.id);
|
||||
}
|
||||
|
||||
this.props.navigation.dispatch(backAction);
|
||||
navigation.dispatch(backAction);
|
||||
};
|
||||
|
||||
handleSearch = (term) => {
|
||||
|
|
@ -160,9 +157,8 @@ export default class ExtensionTeam extends PureComponent {
|
|||
};
|
||||
|
||||
renderItem = ({item}) => {
|
||||
const {navigation} = this.props;
|
||||
const {params = {}} = navigation.state;
|
||||
const {currentChannelId} = params;
|
||||
const {route} = this.props;
|
||||
const {currentChannelId} = route.params;
|
||||
|
||||
return (
|
||||
<ExtensionChannelItem
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {PureComponent} from 'react';
|
||||
import {NavigationActions} from 'react-navigation';
|
||||
import TouchableItem from 'react-navigation-stack/lib/module/views/TouchableItem';
|
||||
import {CommonActions as NavigationActions} from '@react-navigation/native';
|
||||
import TouchableItem from '@react-navigation/stack/lib/module/views/TouchableItem';
|
||||
import PropTypes from 'prop-types';
|
||||
import {intlShape} from 'react-intl';
|
||||
|
||||
|
|
@ -32,7 +32,6 @@ import {MAX_FILE_COUNT} from 'app/constants/post_draft';
|
|||
import {getCurrentServerUrl, getAppCredentials} from 'app/init/credentials';
|
||||
import mattermostManaged from 'app/mattermost_managed';
|
||||
import {getExtensionFromMime} from 'app/utils/file';
|
||||
import {emptyFunction} from 'app/utils/general';
|
||||
import {setCSRFFromCookie} from 'app/utils/security';
|
||||
import {preventDoubleTap} from 'app/utils/tap';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
|
||||
|
|
@ -64,12 +63,10 @@ const MAX_MESSAGE_LENGTH = 4000;
|
|||
|
||||
export default class ExtensionPost extends PureComponent {
|
||||
static propTypes = {
|
||||
actions: PropTypes.shape({
|
||||
getTeamChannels: PropTypes.func.isRequired,
|
||||
}).isRequired,
|
||||
channelId: PropTypes.string,
|
||||
channels: PropTypes.object.isRequired,
|
||||
currentUserId: PropTypes.string.isRequired,
|
||||
getTeamChannels: PropTypes.func.isRequired,
|
||||
maxFileSize: PropTypes.number.isRequired,
|
||||
navigation: PropTypes.object.isRequired,
|
||||
teamId: PropTypes.string.isRequired,
|
||||
|
|
@ -79,57 +76,10 @@ export default class ExtensionPost extends PureComponent {
|
|||
intl: intlShape,
|
||||
};
|
||||
|
||||
static navigationOptions = ({navigation}) => {
|
||||
const {params = {}} = navigation.state;
|
||||
const title = params.title || '';
|
||||
const headerLeft = (
|
||||
<TouchableItem
|
||||
accessibilityComponentType='button'
|
||||
accessibilityTraits='button'
|
||||
borderless={true}
|
||||
delayPressIn={0}
|
||||
pressColorAndroid='rgba(0, 0, 0, .32)'
|
||||
onPress={params.close ? params.close : emptyFunction}
|
||||
>
|
||||
<View style={styles.left}>
|
||||
<MaterialIcon
|
||||
name='close'
|
||||
style={styles.closeButton}
|
||||
/>
|
||||
</View>
|
||||
</TouchableItem>
|
||||
);
|
||||
|
||||
let headerRight = null;
|
||||
|
||||
if (params.post) {
|
||||
headerRight = (
|
||||
<TouchableItem
|
||||
accessibilityComponentType='button'
|
||||
accessibilityTraits='button'
|
||||
borderless={true}
|
||||
delayPressIn={0}
|
||||
pressColorAndroid='rgba(0, 0, 0, .32)'
|
||||
onPress={params.post}
|
||||
>
|
||||
<View style={styles.left}>
|
||||
<PaperPlane
|
||||
color={defaultTheme.sidebarHeaderTextColor}
|
||||
height={20}
|
||||
width={20}
|
||||
/>
|
||||
</View>
|
||||
</TouchableItem>
|
||||
);
|
||||
}
|
||||
|
||||
return {headerLeft, headerRight, title};
|
||||
};
|
||||
|
||||
constructor(props, context) {
|
||||
super(props, context);
|
||||
|
||||
props.navigation.setParams({
|
||||
props.navigation.setOptions({
|
||||
title: context.intl.formatMessage({
|
||||
id: 'mobile.extension.title',
|
||||
defaultMessage: 'Share in Mattermost',
|
||||
|
|
@ -147,8 +97,8 @@ export default class ExtensionPost extends PureComponent {
|
|||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.navigation.setParams({
|
||||
close: this.onClose,
|
||||
this.props.navigation.setOptions({
|
||||
headerLeft: this.leftHeader,
|
||||
});
|
||||
this.auth();
|
||||
}
|
||||
|
|
@ -191,6 +141,20 @@ export default class ExtensionPost extends PureComponent {
|
|||
return this.initialize();
|
||||
};
|
||||
|
||||
canPost = (error, text, extensionFiles, calculatedSize) => {
|
||||
const {maxFileSize} = this.props;
|
||||
const files = extensionFiles || this.state.files;
|
||||
const totalSize = calculatedSize || this.state.totalSize;
|
||||
const filesOK = files.length ? files.length <= MAX_FILE_COUNT : false;
|
||||
const sizeOK = totalSize ? totalSize <= maxFileSize : false;
|
||||
|
||||
if (!error && ((filesOK && sizeOK) || text.length)) {
|
||||
this.props.navigation.setOptions({headerRight: this.rightHeader});
|
||||
} else {
|
||||
this.props.navigation.setOptions({headerRight: null});
|
||||
}
|
||||
}
|
||||
|
||||
showNotSecuredAlert(vendor) {
|
||||
const {formatMessage} = this.context.intl;
|
||||
|
||||
|
|
@ -259,7 +223,7 @@ export default class ExtensionPost extends PureComponent {
|
|||
const {formatMessage} = this.context.intl;
|
||||
const {navigation} = this.props;
|
||||
const navigateAction = NavigationActions.navigate({
|
||||
routeName: 'Channels',
|
||||
name: 'Channels',
|
||||
params: {
|
||||
title: formatMessage({
|
||||
id: 'mobile.routes.selectChannel',
|
||||
|
|
@ -276,7 +240,7 @@ export default class ExtensionPost extends PureComponent {
|
|||
const {formatMessage} = this.context.intl;
|
||||
const {navigation} = this.props;
|
||||
const navigateAction = NavigationActions.navigate({
|
||||
routeName: 'Teams',
|
||||
name: 'Teams',
|
||||
params: {
|
||||
title: formatMessage({
|
||||
id: 'mobile.routes.selectTeam',
|
||||
|
|
@ -314,6 +278,7 @@ export default class ExtensionPost extends PureComponent {
|
|||
};
|
||||
|
||||
handleTextChange = (value) => {
|
||||
this.canPost(null, value);
|
||||
this.setState({value});
|
||||
};
|
||||
|
||||
|
|
@ -336,15 +301,33 @@ export default class ExtensionPost extends PureComponent {
|
|||
return this.setState({hasPermission: false});
|
||||
};
|
||||
|
||||
leftHeader = () => (
|
||||
<TouchableItem
|
||||
accessibilityComponentType='button'
|
||||
accessibilityTraits='button'
|
||||
borderless={true}
|
||||
delayPressIn={0}
|
||||
pressColorAndroid='rgba(0, 0, 0, .32)'
|
||||
onPress={this.onClose}
|
||||
>
|
||||
<View style={styles.left}>
|
||||
<MaterialIcon
|
||||
name='close'
|
||||
style={styles.closeButton}
|
||||
/>
|
||||
</View>
|
||||
</TouchableItem>
|
||||
);
|
||||
|
||||
loadData = async (items) => {
|
||||
const {actions, maxFileSize, teamId} = this.props;
|
||||
const {getTeamChannels, teamId} = this.props;
|
||||
if (this.token && this.url) {
|
||||
const text = [];
|
||||
const files = [];
|
||||
let totalSize = 0;
|
||||
let error;
|
||||
|
||||
actions.getTeamChannels(teamId);
|
||||
getTeamChannels(teamId);
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
const item = items[i];
|
||||
|
|
@ -387,12 +370,7 @@ export default class ExtensionPost extends PureComponent {
|
|||
}
|
||||
|
||||
const value = text.join('\n');
|
||||
|
||||
if (!error && files.length <= MAX_FILE_COUNT && totalSize <= maxFileSize) {
|
||||
this.props.navigation.setParams({
|
||||
post: this.onPost,
|
||||
});
|
||||
}
|
||||
this.canPost(error, value, files, totalSize);
|
||||
|
||||
this.setState({error, files, value, hasPermission: true, totalSize});
|
||||
}
|
||||
|
|
@ -570,6 +548,25 @@ export default class ExtensionPost extends PureComponent {
|
|||
});
|
||||
};
|
||||
|
||||
rightHeader = () => (
|
||||
<TouchableItem
|
||||
accessibilityComponentType='button'
|
||||
accessibilityTraits='button'
|
||||
borderless={true}
|
||||
delayPressIn={0}
|
||||
pressColorAndroid='rgba(0, 0, 0, .32)'
|
||||
onPress={this.onPost}
|
||||
>
|
||||
<View style={styles.left}>
|
||||
<PaperPlane
|
||||
color={defaultTheme.sidebarHeaderTextColor}
|
||||
height={20}
|
||||
width={20}
|
||||
/>
|
||||
</View>
|
||||
</TouchableItem>
|
||||
);
|
||||
|
||||
renderTeamButton = () => {
|
||||
const {teamId} = this.state;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import ExtensionPost from './extension_post';
|
|||
jest.spyOn(Alert, 'alert').mockReturnValue(true);
|
||||
jest.spyOn(PermissionsAndroid, 'check').mockReturnValue(PermissionsAndroid.RESULTS.GRANTED);
|
||||
|
||||
jest.mock('react-navigation-stack/lib/module/views/TouchableItem', () => null);
|
||||
jest.mock('@react-navigation/stack/lib/module/views/TouchableItem', () => null);
|
||||
|
||||
jest.mock('app/mattermost_managed', () => ({
|
||||
getConfig: jest.fn().mockReturnValue(false),
|
||||
|
|
@ -20,15 +20,16 @@ const MAX_MESSAGE_LENGTH = 4000;
|
|||
|
||||
describe('ExtensionPost', () => {
|
||||
const baseProps = {
|
||||
actions: {
|
||||
getTeamChannels: jest.fn(),
|
||||
},
|
||||
channelId: 'channel-id',
|
||||
channels: {},
|
||||
currentUserId: 'current-user-id',
|
||||
getTeamChannels: jest.fn(),
|
||||
maxFileSize: 1024,
|
||||
navigation: {
|
||||
setParams: jest.fn(),
|
||||
setOptions: jest.fn(),
|
||||
},
|
||||
route: {
|
||||
params: {},
|
||||
},
|
||||
teamId: 'team-id',
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {bindActionCreators} from 'redux';
|
||||
import {connect} from 'react-redux';
|
||||
|
||||
import {getAllChannels, getCurrentChannel, getDefaultChannel} from '@mm-redux/selectors/entities/channels';
|
||||
|
|
@ -18,7 +17,7 @@ function mapStateToProps(state) {
|
|||
const config = getConfig(state);
|
||||
|
||||
let channel = getCurrentChannel(state);
|
||||
if (channel && channel.delete_at !== 0) {
|
||||
if (channel && (channel.delete_at !== 0)) {
|
||||
channel = getDefaultChannel(state);
|
||||
}
|
||||
|
||||
|
|
@ -31,12 +30,8 @@ function mapStateToProps(state) {
|
|||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return {
|
||||
actions: bindActionCreators({
|
||||
getTeamChannels,
|
||||
}, dispatch),
|
||||
};
|
||||
}
|
||||
const mapDispatchToProps = ({
|
||||
getTeamChannels,
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(ExtensionPost);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
import React, {PureComponent} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {intlShape} from 'react-intl';
|
||||
import {NavigationActions} from 'react-navigation';
|
||||
import {CommonActions as NavigationActions} from '@react-navigation/native';
|
||||
import {
|
||||
ActivityIndicator,
|
||||
FlatList,
|
||||
|
|
@ -26,6 +26,7 @@ export default class ExtensionTeam extends PureComponent {
|
|||
getTeamChannels: PropTypes.func.isRequired,
|
||||
}).isRequired,
|
||||
navigation: PropTypes.object.isRequired,
|
||||
route: PropTypes.object.isRequired,
|
||||
teamIds: PropTypes.array,
|
||||
};
|
||||
|
||||
|
|
@ -37,26 +38,22 @@ export default class ExtensionTeam extends PureComponent {
|
|||
intl: intlShape,
|
||||
};
|
||||
|
||||
static navigationOptions = ({navigation}) => ({
|
||||
title: navigation.state.params.title,
|
||||
});
|
||||
|
||||
state = {
|
||||
loading: false,
|
||||
};
|
||||
|
||||
handleSelectTeam = async (teamId) => {
|
||||
const {state} = this.props.navigation;
|
||||
const backAction = NavigationActions.back();
|
||||
const {actions, navigation, route} = this.props;
|
||||
const backAction = NavigationActions.goBack();
|
||||
|
||||
if (state.params && state.params.onSelectTeam) {
|
||||
if (route?.params?.onSelectTeam) {
|
||||
this.setState({loading: true});
|
||||
const channelId = await this.props.actions.getTeamChannels(teamId);
|
||||
this.props.actions.extensionSelectTeamId(teamId);
|
||||
state.params.onSelectTeam(teamId, channelId);
|
||||
const channelId = await actions.getTeamChannels(teamId);
|
||||
actions.extensionSelectTeamId(teamId);
|
||||
route.params.onSelectTeam(teamId, channelId);
|
||||
}
|
||||
|
||||
this.props.navigation.dispatch(backAction);
|
||||
navigation.dispatch(backAction);
|
||||
};
|
||||
|
||||
keyExtractor = (item) => item;
|
||||
|
|
@ -70,8 +67,7 @@ export default class ExtensionTeam extends PureComponent {
|
|||
};
|
||||
|
||||
renderItem = ({item}) => {
|
||||
const {navigation} = this.props;
|
||||
const {params} = navigation.state;
|
||||
const {params} = this.props.route;
|
||||
|
||||
return (
|
||||
<TeamItem
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {createAppContainer} from 'react-navigation';
|
||||
import {createStackNavigator} from 'react-navigation-stack';
|
||||
import React from 'react';
|
||||
import {NavigationContainer} from '@react-navigation/native';
|
||||
import {createStackNavigator} from '@react-navigation/stack';
|
||||
|
||||
import {Preferences} from '@mm-redux/constants';
|
||||
|
||||
|
|
@ -11,32 +12,49 @@ import ExtensionPost from './extension_post';
|
|||
import ExtensionTeams from './extension_teams';
|
||||
|
||||
const theme = Preferences.THEMES.default;
|
||||
const Navigation = createStackNavigator({
|
||||
Post: {
|
||||
screen: ExtensionPost,
|
||||
const Stack = createStackNavigator();
|
||||
const defaultNavigationOptions = {
|
||||
headerStyle: {
|
||||
backgroundColor: theme.sidebarHeaderBg,
|
||||
},
|
||||
Teams: {
|
||||
screen: ExtensionTeams,
|
||||
headerTitleStyle: {
|
||||
marginHorizontal: 0,
|
||||
left: 0,
|
||||
color: theme.sidebarHeaderTextColor,
|
||||
},
|
||||
Channels: {
|
||||
screen: ExtensionChannels,
|
||||
headerBackTitleStyle: {
|
||||
color: theme.sidebarHeaderTextColor,
|
||||
margin: 0,
|
||||
},
|
||||
}, {
|
||||
defaultNavigationOptions: {
|
||||
headerStyle: {
|
||||
backgroundColor: theme.sidebarHeaderBg,
|
||||
},
|
||||
headerTitleStyle: {
|
||||
marginHorizontal: 0,
|
||||
left: 0,
|
||||
color: theme.sidebarHeaderTextColor,
|
||||
},
|
||||
headerBackTitleStyle: {
|
||||
color: theme.sidebarHeaderTextColor,
|
||||
margin: 0,
|
||||
},
|
||||
headerTintColor: theme.sidebarHeaderTextColor,
|
||||
},
|
||||
});
|
||||
headerTintColor: theme.sidebarHeaderTextColor,
|
||||
};
|
||||
|
||||
export default createAppContainer(Navigation);
|
||||
function RootStack() {
|
||||
return (
|
||||
<Stack.Navigator
|
||||
initialRouteName='Post'
|
||||
screenOptions={defaultNavigationOptions}
|
||||
>
|
||||
<Stack.Screen
|
||||
name='Post'
|
||||
component={ExtensionPost}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name='Teams'
|
||||
component={ExtensionTeams}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name='Channels'
|
||||
component={ExtensionChannels}
|
||||
/>
|
||||
</Stack.Navigator>
|
||||
);
|
||||
}
|
||||
|
||||
export default function ExtensionNavigation() {
|
||||
return (
|
||||
<NavigationContainer>
|
||||
<RootStack/>
|
||||
</NavigationContainer>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,15 +109,6 @@ jest.doMock('react-native', () => {
|
|||
jest.mock('react-native/Libraries/Animated/src/NativeAnimatedHelper');
|
||||
jest.mock('../node_modules/react-native/Libraries/EventEmitter/NativeEventEmitter');
|
||||
|
||||
jest.mock('react-native-cookies', () => ({
|
||||
addEventListener: jest.fn(),
|
||||
removeEventListener: jest.fn(),
|
||||
openURL: jest.fn(),
|
||||
canOpenURL: jest.fn(),
|
||||
getInitialURL: jest.fn(),
|
||||
clearAll: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('react-native-device-info', () => {
|
||||
return {
|
||||
getVersion: () => '0.0.0',
|
||||
|
|
@ -125,12 +116,11 @@ jest.mock('react-native-device-info', () => {
|
|||
getModel: () => 'iPhone X',
|
||||
isTablet: () => false,
|
||||
getApplicationName: () => 'Mattermost',
|
||||
getDeviceLocale: () => 'en-US',
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('react-native-fast-image', () => {
|
||||
const FastImage = require.requireActual('react-native-fast-image').default;
|
||||
const FastImage = jest.requireActual('react-native-fast-image').default;
|
||||
FastImage.preload = jest.fn();
|
||||
|
||||
return FastImage;
|
||||
|
|
@ -162,8 +152,33 @@ jest.mock('rn-fetch-blob/fs', () => ({
|
|||
mv: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('react-native-localize', () => ({
|
||||
getTimeZone: () => 'World/Somewhere',
|
||||
getLocales: () => ([
|
||||
{countryCode: 'GB', languageTag: 'en-GB', languageCode: 'en', isRTL: false},
|
||||
{countryCode: 'US', languageTag: 'en-US', languageCode: 'en', isRTL: false},
|
||||
{countryCode: 'FR', languageTag: 'fr-FR', languageCode: 'fr', isRTL: false},
|
||||
]),
|
||||
}));
|
||||
|
||||
jest.mock('@react-native-community/cookies', () => ({
|
||||
addEventListener: jest.fn(),
|
||||
removeEventListener: jest.fn(),
|
||||
openURL: jest.fn(),
|
||||
canOpenURL: jest.fn(),
|
||||
getInitialURL: jest.fn(),
|
||||
clearAll: jest.fn(),
|
||||
get: () => Promise.resolve(({
|
||||
res: {
|
||||
MMCSRF: {
|
||||
value: 'the cookie',
|
||||
},
|
||||
},
|
||||
})),
|
||||
}));
|
||||
|
||||
jest.mock('react-native-navigation', () => {
|
||||
const RNN = require.requireActual('react-native-navigation');
|
||||
const RNN = jest.requireActual('react-native-navigation');
|
||||
return {
|
||||
...RNN,
|
||||
Navigation: {
|
||||
|
|
|
|||
Loading…
Reference in a new issue