[IMPROVE] - migrating the last container files (finished)
This commit is contained in:
parent
2c9f6f7f82
commit
9179e90920
|
@ -1,8 +1,5 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {
|
import { View, StyleSheet, Text, Animated, Easing, Linking } from 'react-native';
|
||||||
View, StyleSheet, Text, Animated, Easing, Linking
|
|
||||||
} from 'react-native';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { Base64 } from 'js-base64';
|
import { Base64 } from 'js-base64';
|
||||||
import * as AppleAuthentication from 'expo-apple-authentication';
|
import * as AppleAuthentication from 'expo-apple-authentication';
|
||||||
|
@ -60,21 +57,41 @@ const styles = StyleSheet.create({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
class LoginServices extends React.PureComponent {
|
type TOpenOAuth = {
|
||||||
static propTypes = {
|
url?: string;
|
||||||
navigation: PropTypes.object,
|
ssoToken?: string;
|
||||||
server: PropTypes.string,
|
authType?: string;
|
||||||
services: PropTypes.object,
|
}
|
||||||
Gitlab_URL: PropTypes.string,
|
|
||||||
CAS_enabled: PropTypes.bool,
|
|
||||||
CAS_login_url: PropTypes.string,
|
|
||||||
separator: PropTypes.bool,
|
|
||||||
theme: PropTypes.string
|
|
||||||
}
|
|
||||||
|
|
||||||
static defaultProps = {
|
type TService = {
|
||||||
separator: true
|
name: string;
|
||||||
}
|
service: string;
|
||||||
|
authType: string;
|
||||||
|
buttonColor: string;
|
||||||
|
buttonLabelColor: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface ILoginServicesProps {
|
||||||
|
navigation: any;
|
||||||
|
server: string;
|
||||||
|
services: {
|
||||||
|
facebook: {clientId: string;};
|
||||||
|
github: {clientId: string;};
|
||||||
|
gitlab: {clientId: string;};
|
||||||
|
google: {clientId: string;};
|
||||||
|
linkedin: {clientId: string;};
|
||||||
|
'meteor-developer': {clientId: string;};
|
||||||
|
wordpress: {clientId: string; serverURL: string;};
|
||||||
|
};
|
||||||
|
Gitlab_URL: string;
|
||||||
|
CAS_enabled: boolean;
|
||||||
|
CAS_login_url: string;
|
||||||
|
separator: boolean;
|
||||||
|
theme: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
class LoginServices extends React.PureComponent<ILoginServicesProps, any> {
|
||||||
|
private _animation: any;
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
collapsed: true,
|
collapsed: true,
|
||||||
|
@ -173,7 +190,7 @@ class LoginServices extends React.PureComponent {
|
||||||
this.openOAuth({ url: `${ endpoint }${ params }` });
|
this.openOAuth({ url: `${ endpoint }${ params }` });
|
||||||
}
|
}
|
||||||
|
|
||||||
onPressCustomOAuth = (loginService) => {
|
onPressCustomOAuth = (loginService: any) => {
|
||||||
logEvent(events.ENTER_WITH_CUSTOM_OAUTH);
|
logEvent(events.ENTER_WITH_CUSTOM_OAUTH);
|
||||||
const { server } = this.props;
|
const { server } = this.props;
|
||||||
const {
|
const {
|
||||||
|
@ -188,7 +205,7 @@ class LoginServices extends React.PureComponent {
|
||||||
this.openOAuth({ url });
|
this.openOAuth({ url });
|
||||||
}
|
}
|
||||||
|
|
||||||
onPressSaml = (loginService) => {
|
onPressSaml = (loginService: any) => {
|
||||||
logEvent(events.ENTER_WITH_SAML);
|
logEvent(events.ENTER_WITH_SAML);
|
||||||
const { server } = this.props;
|
const { server } = this.props;
|
||||||
const { clientConfig } = loginService;
|
const { clientConfig } = loginService;
|
||||||
|
@ -224,7 +241,7 @@ class LoginServices extends React.PureComponent {
|
||||||
|
|
||||||
getOAuthState = (loginStyle = LOGIN_STYPE_POPUP) => {
|
getOAuthState = (loginStyle = LOGIN_STYPE_POPUP) => {
|
||||||
const credentialToken = random(43);
|
const credentialToken = random(43);
|
||||||
let obj = { loginStyle, credentialToken, isCordova: true };
|
let obj: any = { loginStyle, credentialToken, isCordova: true };
|
||||||
if (loginStyle === LOGIN_STYPE_REDIRECT) {
|
if (loginStyle === LOGIN_STYPE_REDIRECT) {
|
||||||
obj = {
|
obj = {
|
||||||
...obj,
|
...obj,
|
||||||
|
@ -234,19 +251,21 @@ class LoginServices extends React.PureComponent {
|
||||||
return Base64.encodeURI(JSON.stringify(obj));
|
return Base64.encodeURI(JSON.stringify(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
openOAuth = ({ url, ssoToken, authType = 'oauth' }) => {
|
openOAuth = ({ url, ssoToken, authType = 'oauth' }: TOpenOAuth) => {
|
||||||
const { navigation } = this.props;
|
const { navigation } = this.props;
|
||||||
navigation.navigate('AuthenticationWebView', { url, authType, ssoToken });
|
navigation.navigate('AuthenticationWebView', { url, authType, ssoToken });
|
||||||
}
|
}
|
||||||
|
|
||||||
transitionServicesTo = (height) => {
|
transitionServicesTo = (height: number) => {
|
||||||
const { servicesHeight } = this.state;
|
const { servicesHeight } = this.state;
|
||||||
if (this._animation) {
|
if (this._animation) {
|
||||||
this._animation.stop();
|
this._animation.stop();
|
||||||
}
|
}
|
||||||
|
// @ts-ignore
|
||||||
this._animation = Animated.timing(servicesHeight, {
|
this._animation = Animated.timing(servicesHeight, {
|
||||||
toValue: height,
|
toValue: height,
|
||||||
duration: 300,
|
duration: 300,
|
||||||
|
// @ts-ignore
|
||||||
easing: Easing.easeOutCubic
|
easing: Easing.easeOutCubic
|
||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
@ -260,11 +279,11 @@ class LoginServices extends React.PureComponent {
|
||||||
} else {
|
} else {
|
||||||
this.transitionServicesTo(SERVICES_COLLAPSED_HEIGHT);
|
this.transitionServicesTo(SERVICES_COLLAPSED_HEIGHT);
|
||||||
}
|
}
|
||||||
this.setState(prevState => ({ collapsed: !prevState.collapsed }));
|
this.setState((prevState: any) => ({ collapsed: !prevState.collapsed }));
|
||||||
}
|
}
|
||||||
|
|
||||||
getSocialOauthProvider = (name) => {
|
getSocialOauthProvider = (name: string) => {
|
||||||
const oauthProviders = {
|
const oauthProviders: any = {
|
||||||
facebook: this.onPressFacebook,
|
facebook: this.onPressFacebook,
|
||||||
github: this.onPressGithub,
|
github: this.onPressGithub,
|
||||||
gitlab: this.onPressGitlab,
|
gitlab: this.onPressGitlab,
|
||||||
|
@ -303,7 +322,7 @@ class LoginServices extends React.PureComponent {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderItem = (service) => {
|
renderItem = (service: TService) => {
|
||||||
const { CAS_enabled, theme } = this.props;
|
const { CAS_enabled, theme } = this.props;
|
||||||
let { name } = service;
|
let { name } = service;
|
||||||
name = name === 'meteor-developer' ? 'meteor' : name;
|
name = name === 'meteor-developer' ? 'meteor' : name;
|
||||||
|
@ -380,7 +399,7 @@ class LoginServices extends React.PureComponent {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Animated.View style={style}>
|
<Animated.View style={style}>
|
||||||
{Object.values(services).map(service => this.renderItem(service))}
|
{Object.values(services).map((service: any) => this.renderItem(service))}
|
||||||
</Animated.View>
|
</Animated.View>
|
||||||
{this.renderServicesSeparator()}
|
{this.renderServicesSeparator()}
|
||||||
</>
|
</>
|
||||||
|
@ -388,14 +407,14 @@ class LoginServices extends React.PureComponent {
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{Object.values(services).map(service => this.renderItem(service))}
|
{Object.values(services).map((service: any) => this.renderItem(service))}
|
||||||
{this.renderServicesSeparator()}
|
{this.renderServicesSeparator()}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = (state: any) => ({
|
||||||
server: state.server.server,
|
server: state.server.server,
|
||||||
Gitlab_URL: state.settings.API_Gitlab_URL,
|
Gitlab_URL: state.settings.API_Gitlab_URL,
|
||||||
CAS_enabled: state.settings.CAS_enabled,
|
CAS_enabled: state.settings.CAS_enabled,
|
|
@ -1,5 +1,4 @@
|
||||||
import { useImperativeHandle, forwardRef } from 'react';
|
import { useImperativeHandle, forwardRef } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
import RocketChat from '../lib/rocketchat';
|
import RocketChat from '../lib/rocketchat';
|
||||||
import database from '../lib/database';
|
import database from '../lib/database';
|
||||||
|
@ -8,17 +7,17 @@ import { useActionSheet } from './ActionSheet';
|
||||||
import I18n from '../i18n';
|
import I18n from '../i18n';
|
||||||
import log from '../utils/log';
|
import log from '../utils/log';
|
||||||
|
|
||||||
const MessageErrorActions = forwardRef(({ tmid }, ref) => {
|
const MessageErrorActions = forwardRef(({ tmid }: any, ref): any => {
|
||||||
const { showActionSheet } = useActionSheet();
|
const { showActionSheet }: any = useActionSheet();
|
||||||
|
|
||||||
const handleResend = protectedFunction(async(message) => {
|
const handleResend = protectedFunction(async(message: any) => {
|
||||||
await RocketChat.resendMessage(message, tmid);
|
await RocketChat.resendMessage(message, tmid);
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleDelete = async(message) => {
|
const handleDelete = async(message: any) => {
|
||||||
try {
|
try {
|
||||||
const db = database.active;
|
const db = database.active;
|
||||||
const deleteBatch = [];
|
const deleteBatch: any = [];
|
||||||
const msgCollection = db.get('messages');
|
const msgCollection = db.get('messages');
|
||||||
const threadCollection = db.get('threads');
|
const threadCollection = db.get('threads');
|
||||||
|
|
||||||
|
@ -39,7 +38,7 @@ const MessageErrorActions = forwardRef(({ tmid }, ref) => {
|
||||||
const msg = await msgCollection.find(tmid);
|
const msg = await msgCollection.find(tmid);
|
||||||
if (msg.tcount <= 1) {
|
if (msg.tcount <= 1) {
|
||||||
deleteBatch.push(
|
deleteBatch.push(
|
||||||
msg.prepareUpdate((m) => {
|
msg.prepareUpdate((m: any) => {
|
||||||
m.tcount = null;
|
m.tcount = null;
|
||||||
m.tlm = null;
|
m.tlm = null;
|
||||||
})
|
})
|
||||||
|
@ -54,7 +53,7 @@ const MessageErrorActions = forwardRef(({ tmid }, ref) => {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
deleteBatch.push(
|
deleteBatch.push(
|
||||||
msg.prepareUpdate((m) => {
|
msg.prepareUpdate((m: any) => {
|
||||||
m.tcount -= 1;
|
m.tcount -= 1;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
@ -71,7 +70,7 @@ const MessageErrorActions = forwardRef(({ tmid }, ref) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const showMessageErrorActions = (message) => {
|
const showMessageErrorActions = (message: any) => {
|
||||||
showActionSheet({
|
showActionSheet({
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
|
@ -94,8 +93,5 @@ const MessageErrorActions = forwardRef(({ tmid }, ref) => {
|
||||||
showMessageErrorActions
|
showMessageErrorActions
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
MessageErrorActions.propTypes = {
|
|
||||||
tmid: PropTypes.string
|
|
||||||
};
|
|
||||||
|
|
||||||
export default MessageErrorActions;
|
export default MessageErrorActions;
|
|
@ -62,12 +62,35 @@ const styles = StyleSheet.create({
|
||||||
const standardEmojiStyle = { fontSize: 20 };
|
const standardEmojiStyle = { fontSize: 20 };
|
||||||
const customEmojiStyle = { width: 20, height: 20 };
|
const customEmojiStyle = { width: 20, height: 20 };
|
||||||
|
|
||||||
const Item = React.memo(({
|
type TItem = {
|
||||||
item, user, baseUrl, getCustomEmoji, theme
|
item: {
|
||||||
}) => {
|
usernames: any;
|
||||||
|
emoji: string;
|
||||||
|
};
|
||||||
|
user?: {username: any;};
|
||||||
|
baseUrl?: string;
|
||||||
|
getCustomEmoji?: Function;
|
||||||
|
theme?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type TModalContent = {
|
||||||
|
message: {
|
||||||
|
reactions: any
|
||||||
|
};
|
||||||
|
onClose: Function;
|
||||||
|
theme: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface IReactionsModal {
|
||||||
|
isVisible: boolean;
|
||||||
|
onClose(): void;
|
||||||
|
theme: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Item = React.memo(({ item, user, baseUrl, getCustomEmoji, theme }: TItem) => {
|
||||||
const count = item.usernames.length;
|
const count = item.usernames.length;
|
||||||
let usernames = item.usernames.slice(0, 3)
|
let usernames = item.usernames.slice(0, 3)
|
||||||
.map(username => (username === user.username ? I18n.t('you') : username)).join(', ');
|
.map((username: any) => (username === user?.username ? I18n.t('you') : username)).join(', ');
|
||||||
if (count > 3) {
|
if (count > 3) {
|
||||||
usernames = `${ usernames } ${ I18n.t('and_more') } ${ count - 3 }`;
|
usernames = `${ usernames } ${ I18n.t('and_more') } ${ count - 3 }`;
|
||||||
} else {
|
} else {
|
||||||
|
@ -80,23 +103,21 @@ const Item = React.memo(({
|
||||||
content={item.emoji}
|
content={item.emoji}
|
||||||
standardEmojiStyle={standardEmojiStyle}
|
standardEmojiStyle={standardEmojiStyle}
|
||||||
customEmojiStyle={customEmojiStyle}
|
customEmojiStyle={customEmojiStyle}
|
||||||
baseUrl={baseUrl}
|
baseUrl={baseUrl!}
|
||||||
getCustomEmoji={getCustomEmoji}
|
getCustomEmoji={getCustomEmoji!}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
<View style={styles.peopleItemContainer}>
|
<View style={styles.peopleItemContainer}>
|
||||||
<Text style={[styles.reactCount, { color: themes[theme].buttonText }]}>
|
<Text style={[styles.reactCount, { color: themes[theme!].buttonText }]}>
|
||||||
{count === 1 ? I18n.t('1_person_reacted') : I18n.t('N_people_reacted', { n: count })}
|
{count === 1 ? I18n.t('1_person_reacted') : I18n.t('N_people_reacted', { n: count })}
|
||||||
</Text>
|
</Text>
|
||||||
<Text style={[styles.peopleReacted, { color: themes[theme].buttonText }]}>{ usernames }</Text>
|
<Text style={[styles.peopleReacted, { color: themes[theme!].buttonText }]}>{ usernames }</Text>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const ModalContent = React.memo(({
|
const ModalContent = React.memo(({ message, onClose, ...props }: TModalContent) => {
|
||||||
message, onClose, ...props
|
|
||||||
}) => {
|
|
||||||
if (message && message.reactions) {
|
if (message && message.reactions) {
|
||||||
return (
|
return (
|
||||||
<SafeAreaView style={styles.safeArea}>
|
<SafeAreaView style={styles.safeArea}>
|
||||||
|
@ -122,9 +143,7 @@ const ModalContent = React.memo(({
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
const ReactionsModal = React.memo(({
|
const ReactionsModal = React.memo(({ isVisible, onClose, theme, ...props }: IReactionsModal) => (
|
||||||
isVisible, onClose, theme, ...props
|
|
||||||
}) => (
|
|
||||||
<Modal
|
<Modal
|
||||||
isVisible={isVisible}
|
isVisible={isVisible}
|
||||||
onBackdropPress={onClose}
|
onBackdropPress={onClose}
|
||||||
|
@ -133,31 +152,13 @@ const ReactionsModal = React.memo(({
|
||||||
onSwipeComplete={onClose}
|
onSwipeComplete={onClose}
|
||||||
swipeDirection={['up', 'left', 'right', 'down']}
|
swipeDirection={['up', 'left', 'right', 'down']}
|
||||||
>
|
>
|
||||||
|
{/*@ts-ignore*/}
|
||||||
<ModalContent onClose={onClose} theme={theme} {...props} />
|
<ModalContent onClose={onClose} theme={theme} {...props} />
|
||||||
</Modal>
|
</Modal>
|
||||||
), (prevProps, nextProps) => prevProps.isVisible === nextProps.isVisible && prevProps.theme === nextProps.theme);
|
), (prevProps, nextProps) => prevProps.isVisible === nextProps.isVisible && prevProps.theme === nextProps.theme);
|
||||||
|
|
||||||
ReactionsModal.propTypes = {
|
|
||||||
isVisible: PropTypes.bool,
|
|
||||||
onClose: PropTypes.func,
|
|
||||||
theme: PropTypes.string
|
|
||||||
};
|
|
||||||
ReactionsModal.displayName = 'ReactionsModal';
|
ReactionsModal.displayName = 'ReactionsModal';
|
||||||
|
|
||||||
ModalContent.propTypes = {
|
|
||||||
message: PropTypes.object,
|
|
||||||
onClose: PropTypes.func,
|
|
||||||
theme: PropTypes.string
|
|
||||||
};
|
|
||||||
ModalContent.displayName = 'ReactionsModalContent';
|
ModalContent.displayName = 'ReactionsModalContent';
|
||||||
|
|
||||||
Item.propTypes = {
|
|
||||||
item: PropTypes.object,
|
|
||||||
user: PropTypes.object,
|
|
||||||
baseUrl: PropTypes.string,
|
|
||||||
getCustomEmoji: PropTypes.func,
|
|
||||||
theme: PropTypes.string
|
|
||||||
};
|
|
||||||
Item.displayName = 'ReactionsModalItem';
|
Item.displayName = 'ReactionsModalItem';
|
||||||
|
|
||||||
export default withTheme(ReactionsModal);
|
export default withTheme(ReactionsModal);
|
|
@ -1,6 +1,5 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { View, StyleSheet, Text } from 'react-native';
|
import { View, StyleSheet, Text } from 'react-native';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import Touchable from 'react-native-platform-touchable';
|
import Touchable from 'react-native-platform-touchable';
|
||||||
|
|
||||||
import TextInput from '../presentation/TextInput';
|
import TextInput from '../presentation/TextInput';
|
||||||
|
@ -45,7 +44,17 @@ const styles = StyleSheet.create({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const CancelButton = (onCancelPress, theme) => (
|
interface ISearchBox {
|
||||||
|
onChangeText: Function;
|
||||||
|
onSubmitEditing: Function;
|
||||||
|
hasCancel: boolean;
|
||||||
|
onCancelPress: Function;
|
||||||
|
theme: string;
|
||||||
|
inputRef: any;
|
||||||
|
testID?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CancelButton = (onCancelPress: Function, theme: string) => (
|
||||||
<Touchable onPress={onCancelPress} style={styles.cancel}>
|
<Touchable onPress={onCancelPress} style={styles.cancel}>
|
||||||
<Text style={[styles.cancelText, { color: themes[theme].headerTintColor }]}>{I18n.t('Cancel')}</Text>
|
<Text style={[styles.cancelText, { color: themes[theme].headerTintColor }]}>{I18n.t('Cancel')}</Text>
|
||||||
</Touchable>
|
</Touchable>
|
||||||
|
@ -53,7 +62,7 @@ const CancelButton = (onCancelPress, theme) => (
|
||||||
|
|
||||||
const SearchBox = ({
|
const SearchBox = ({
|
||||||
onChangeText, onSubmitEditing, testID, hasCancel, onCancelPress, inputRef, theme, ...props
|
onChangeText, onSubmitEditing, testID, hasCancel, onCancelPress, inputRef, theme, ...props
|
||||||
}) => (
|
}: ISearchBox) => (
|
||||||
<View
|
<View
|
||||||
style={[
|
style={[
|
||||||
styles.container,
|
styles.container,
|
||||||
|
@ -64,6 +73,7 @@ const SearchBox = ({
|
||||||
<CustomIcon name='search' size={14} color={themes[theme].auxiliaryText} />
|
<CustomIcon name='search' size={14} color={themes[theme].auxiliaryText} />
|
||||||
<TextInput
|
<TextInput
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
|
/*@ts-ignore*/
|
||||||
autoCapitalize='none'
|
autoCapitalize='none'
|
||||||
autoCorrect={false}
|
autoCorrect={false}
|
||||||
blurOnSubmit
|
blurOnSubmit
|
||||||
|
@ -83,14 +93,4 @@ const SearchBox = ({
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
|
||||||
SearchBox.propTypes = {
|
|
||||||
onChangeText: PropTypes.func.isRequired,
|
|
||||||
onSubmitEditing: PropTypes.func,
|
|
||||||
hasCancel: PropTypes.bool,
|
|
||||||
onCancelPress: PropTypes.func,
|
|
||||||
theme: PropTypes.string,
|
|
||||||
inputRef: PropTypes.func,
|
|
||||||
testID: PropTypes.string
|
|
||||||
};
|
|
||||||
|
|
||||||
export default withTheme(SearchBox);
|
export default withTheme(SearchBox);
|
Loading…
Reference in New Issue