Chore: add eslint-plugin-react-hooks lib (#4021)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
This commit is contained in:
parent
53eb251476
commit
b0d408ebc8
10
.eslintrc.js
10
.eslintrc.js
|
@ -17,7 +17,7 @@ module.exports = {
|
|||
legacyDecorators: true
|
||||
}
|
||||
},
|
||||
plugins: ['react', 'jsx-a11y', 'import', 'react-native', '@babel', 'jest'],
|
||||
plugins: ['react', 'jsx-a11y', 'import', 'react-native', '@babel', 'jest', 'react-hooks'],
|
||||
env: {
|
||||
browser: true,
|
||||
commonjs: true,
|
||||
|
@ -148,7 +148,9 @@ module.exports = {
|
|||
'no-async-promise-executor': [0],
|
||||
'max-classes-per-file': [0],
|
||||
'no-multiple-empty-lines': [0],
|
||||
'no-sequences': 'off'
|
||||
'no-sequences': 'off',
|
||||
'react-hooks/rules-of-hooks': 'error',
|
||||
'react-hooks/exhaustive-deps': 'warn'
|
||||
},
|
||||
globals: {
|
||||
__DEV__: true
|
||||
|
@ -237,7 +239,9 @@ module.exports = {
|
|||
}
|
||||
],
|
||||
'new-cap': 'off',
|
||||
'lines-between-class-members': 'off'
|
||||
'lines-between-class-members': 'off',
|
||||
'react-hooks/rules-of-hooks': 'error',
|
||||
'react-hooks/exhaustive-deps': 'warn'
|
||||
},
|
||||
globals: {
|
||||
JSX: true
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React from 'react';
|
||||
import React, { useContext, memo, useEffect } from 'react';
|
||||
import { NavigationContainer } from '@react-navigation/native';
|
||||
import { createStackNavigator } from '@react-navigation/stack';
|
||||
import { connect } from 'react-redux';
|
||||
|
@ -27,21 +27,23 @@ const SetUsernameStack = () => (
|
|||
|
||||
// App
|
||||
const Stack = createStackNavigator<StackParamList>();
|
||||
const App = React.memo(({ root, isMasterDetail }: { root: string; isMasterDetail: boolean }) => {
|
||||
const App = memo(({ root, isMasterDetail }: { root: string; isMasterDetail: boolean }) => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
useEffect(() => {
|
||||
if (root) {
|
||||
const state = Navigation.navigationRef.current?.getRootState();
|
||||
const currentRouteName = getActiveRouteName(state);
|
||||
Navigation.routeNameRef.current = currentRouteName;
|
||||
setCurrentScreen(currentRouteName);
|
||||
}
|
||||
}, [root]);
|
||||
|
||||
if (!root) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { theme } = React.useContext(ThemeContext);
|
||||
const navTheme = navigationTheme(theme);
|
||||
|
||||
React.useEffect(() => {
|
||||
const state = Navigation.navigationRef.current?.getRootState();
|
||||
const currentRouteName = getActiveRouteName(state);
|
||||
Navigation.routeNameRef.current = currentRouteName;
|
||||
setCurrentScreen(currentRouteName);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<NavigationContainer
|
||||
theme={navTheme}
|
||||
|
|
|
@ -30,12 +30,12 @@ const Avatar = React.memo(
|
|||
borderRadius = 4,
|
||||
type = SubscriptionType.DIRECT
|
||||
}: IAvatar) => {
|
||||
const { theme } = useTheme();
|
||||
|
||||
if ((!text && !avatar && !emoji && !rid) || !server) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { theme } = useTheme();
|
||||
|
||||
const avatarStyle = {
|
||||
width: size,
|
||||
height: size,
|
||||
|
|
|
@ -15,10 +15,12 @@ interface IMessageBoxCommandsPreview {
|
|||
|
||||
const CommandsPreview = React.memo(
|
||||
({ commandPreview, showCommandPreview }: IMessageBoxCommandsPreview) => {
|
||||
const { theme } = useTheme();
|
||||
|
||||
if (!showCommandPreview) {
|
||||
return null;
|
||||
}
|
||||
const { theme } = useTheme();
|
||||
|
||||
return (
|
||||
<FlatList
|
||||
testID='commandbox-container'
|
||||
|
|
|
@ -16,10 +16,12 @@ interface IMessageBoxMentions {
|
|||
|
||||
const Mentions = React.memo(
|
||||
({ mentions, trackingType, loading }: IMessageBoxMentions) => {
|
||||
const { theme } = useTheme();
|
||||
|
||||
if (!trackingType) {
|
||||
return null;
|
||||
}
|
||||
const { theme } = useTheme();
|
||||
|
||||
return (
|
||||
<View testID='messagebox-container'>
|
||||
<FlatList
|
||||
|
|
|
@ -56,10 +56,12 @@ interface IMessageBoxReplyPreview {
|
|||
|
||||
const ReplyPreview = React.memo(
|
||||
({ message, Message_TimeFormat, replying, close, useRealName }: IMessageBoxReplyPreview) => {
|
||||
const { theme } = useTheme();
|
||||
|
||||
if (!replying) {
|
||||
return null;
|
||||
}
|
||||
const { theme } = useTheme();
|
||||
|
||||
const time = moment(message.ts).format(Message_TimeFormat);
|
||||
return (
|
||||
<View style={[styles.container, { backgroundColor: themes[theme].messageboxBackground }]}>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* eslint-disable class-methods-use-this */
|
||||
/* eslint-disable react-hooks/rules-of-hooks */
|
||||
import React, { useContext } from 'react';
|
||||
import { StyleSheet, Text } from 'react-native';
|
||||
import { BLOCK_CONTEXT, UiKitParserMessage, UiKitParserModal, uiKitMessage, uiKitModal } from '@rocket.chat/ui-kit';
|
||||
|
|
|
@ -17,12 +17,12 @@ interface IMarkdownPreview {
|
|||
}
|
||||
|
||||
const MarkdownPreview = ({ msg, numberOfLines = 1, testID, style = [] }: IMarkdownPreview) => {
|
||||
const { theme } = useTheme();
|
||||
|
||||
if (!msg) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { theme } = useTheme();
|
||||
|
||||
let m = formatText(msg);
|
||||
m = formatHyperlink(m);
|
||||
m = shortnameToUnicode(m);
|
||||
|
|
|
@ -24,11 +24,12 @@ export type TElement = {
|
|||
};
|
||||
|
||||
const AttachedActions = ({ attachment }: { attachment: IAttachment }) => {
|
||||
const { onAnswerButtonPress } = useContext(MessageContext);
|
||||
const { theme } = useTheme();
|
||||
|
||||
if (!attachment.actions) {
|
||||
return null;
|
||||
}
|
||||
const { onAnswerButtonPress } = useContext(MessageContext);
|
||||
const { theme } = useTheme();
|
||||
|
||||
const attachedButtons = attachment.actions.map((element: TElement) => {
|
||||
const onPress = () => {
|
||||
|
@ -57,12 +58,12 @@ const AttachedActions = ({ attachment }: { attachment: IAttachment }) => {
|
|||
|
||||
const Attachments: React.FC<IMessageAttachments> = React.memo(
|
||||
({ attachments, timeFormat, showAttachment, style, getCustomEmoji, isReply }: IMessageAttachments) => {
|
||||
const { theme } = useTheme();
|
||||
|
||||
if (!attachments || attachments.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { theme } = useTheme();
|
||||
|
||||
const attachmentsElements = attachments.map((file: IAttachment, index: number) => {
|
||||
if (file && file.image_url) {
|
||||
return (
|
||||
|
|
|
@ -81,11 +81,13 @@ interface IMessageReply {
|
|||
|
||||
const Fields = React.memo(
|
||||
({ attachment, getCustomEmoji }: IMessageFields) => {
|
||||
const { theme } = useTheme();
|
||||
const { baseUrl, user } = useContext(MessageContext);
|
||||
|
||||
if (!attachment.fields) {
|
||||
return null;
|
||||
}
|
||||
const { baseUrl, user } = useContext(MessageContext);
|
||||
const { theme } = useTheme();
|
||||
|
||||
return (
|
||||
<>
|
||||
{attachment.fields.map(field => (
|
||||
|
@ -111,11 +113,12 @@ const Fields = React.memo(
|
|||
|
||||
const CollapsibleQuote = React.memo(
|
||||
({ attachment, index, getCustomEmoji }: IMessageReply) => {
|
||||
const { theme } = useTheme();
|
||||
const [collapsed, setCollapsed] = useState(attachment?.collapsed);
|
||||
|
||||
if (!attachment) {
|
||||
return null;
|
||||
}
|
||||
const [collapsed, setCollapsed] = useState(attachment.collapsed);
|
||||
const { theme } = useTheme();
|
||||
|
||||
const onPress = () => {
|
||||
setCollapsed(!collapsed);
|
||||
|
|
|
@ -16,6 +16,8 @@ import { E2E_MESSAGE_TYPE, themes } from '../../lib/constants';
|
|||
const Content = React.memo(
|
||||
(props: IMessageContent) => {
|
||||
const { theme } = useTheme();
|
||||
const { baseUrl, user, onLinkPress } = useContext(MessageContext);
|
||||
|
||||
if (props.isInfo) {
|
||||
// @ts-ignore
|
||||
const infoMessage = getInfoMessage({ ...props });
|
||||
|
@ -49,7 +51,6 @@ const Content = React.memo(
|
|||
} else if (isPreview) {
|
||||
content = <MarkdownPreview msg={props.msg} />;
|
||||
} else {
|
||||
const { baseUrl, user, onLinkPress } = useContext(MessageContext);
|
||||
content = (
|
||||
<Markdown
|
||||
msg={props.msg}
|
||||
|
|
|
@ -10,11 +10,12 @@ import { E2E_MESSAGE_TYPE, themes } from '../../lib/constants';
|
|||
|
||||
const Encrypted = React.memo(({ type }: { type: string }) => {
|
||||
const { theme } = useTheme();
|
||||
const { onEncryptedPress } = useContext(MessageContext);
|
||||
|
||||
if (type !== E2E_MESSAGE_TYPE) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { onEncryptedPress } = useContext(MessageContext);
|
||||
return (
|
||||
<Touchable onPress={onEncryptedPress} style={styles.encrypted} hitSlop={BUTTON_HIT_SLOP}>
|
||||
<CustomIcon name='encrypted' size={16} color={themes[theme].auxiliaryText} />
|
||||
|
|
|
@ -110,6 +110,9 @@ const Message = React.memo((props: IMessage) => {
|
|||
Message.displayName = 'Message';
|
||||
|
||||
const MessageTouchable = React.memo((props: IMessageTouchable & IMessage) => {
|
||||
const { onPress, onLongPress } = useContext(MessageContext);
|
||||
const { theme } = useTheme();
|
||||
|
||||
if (props.hasError) {
|
||||
return (
|
||||
<View>
|
||||
|
@ -117,8 +120,6 @@ const MessageTouchable = React.memo((props: IMessageTouchable & IMessage) => {
|
|||
</View>
|
||||
);
|
||||
}
|
||||
const { onPress, onLongPress } = useContext(MessageContext);
|
||||
const { theme } = useTheme();
|
||||
|
||||
return (
|
||||
<Touchable
|
||||
|
|
|
@ -11,11 +11,12 @@ import { useTheme } from '../../theme';
|
|||
const MessageError = React.memo(
|
||||
({ hasError }: { hasError: boolean }) => {
|
||||
const { theme } = useTheme();
|
||||
const { onErrorPress } = useContext(MessageContext);
|
||||
|
||||
if (!hasError) {
|
||||
return null;
|
||||
}
|
||||
const { onErrorPress } = useContext(MessageContext);
|
||||
|
||||
return (
|
||||
<Touchable onPress={onErrorPress} style={styles.errorButton} hitSlop={BUTTON_HIT_SLOP}>
|
||||
<CustomIcon name='warning' color={themes[theme].dangerColor} size={18} />
|
||||
|
|
|
@ -11,16 +11,7 @@ import { useTheme } from '../../theme';
|
|||
|
||||
const RepliedThread = memo(({ tmid, tmsg, isHeader, fetchThreadName, id, isEncrypted }: IMessageRepliedThread) => {
|
||||
const { theme } = useTheme();
|
||||
|
||||
if (!tmid || !isHeader) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const [msg, setMsg] = useState(isEncrypted ? I18n.t('Encrypted_message') : tmsg);
|
||||
const fetch = async () => {
|
||||
const threadName = fetchThreadName ? await fetchThreadName(tmid, id) : '';
|
||||
setMsg(threadName);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!msg) {
|
||||
|
@ -28,6 +19,15 @@ const RepliedThread = memo(({ tmid, tmsg, isHeader, fetchThreadName, id, isEncry
|
|||
}
|
||||
}, []);
|
||||
|
||||
if (!tmid || !isHeader) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const fetch = async () => {
|
||||
const threadName = fetchThreadName ? await fetchThreadName(tmid, id) : '';
|
||||
setMsg(threadName);
|
||||
};
|
||||
|
||||
if (!msg) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -113,11 +113,13 @@ const Title = React.memo(({ attachment, timeFormat, theme }: { attachment: IAtta
|
|||
|
||||
const Description = React.memo(
|
||||
({ attachment, getCustomEmoji, theme }: { attachment: IAttachment; getCustomEmoji: TGetCustomEmoji; theme: string }) => {
|
||||
const { baseUrl, user } = useContext(MessageContext);
|
||||
const text = attachment.text || attachment.title;
|
||||
|
||||
if (!text) {
|
||||
return null;
|
||||
}
|
||||
const { baseUrl, user } = useContext(MessageContext);
|
||||
|
||||
return (
|
||||
<Markdown
|
||||
msg={text}
|
||||
|
@ -145,10 +147,12 @@ const Description = React.memo(
|
|||
|
||||
const UrlImage = React.memo(
|
||||
({ image }: { image?: string }) => {
|
||||
const { baseUrl, user } = useContext(MessageContext);
|
||||
|
||||
if (!image) {
|
||||
return null;
|
||||
}
|
||||
const { baseUrl, user } = useContext(MessageContext);
|
||||
|
||||
image = image.includes('http') ? image : `${baseUrl}/${image}?rc_uid=${user.id}&rc_token=${user.token}`;
|
||||
return <FastImage source={{ uri: image }} style={styles.image} resizeMode={FastImage.resizeMode.cover} />;
|
||||
},
|
||||
|
@ -157,11 +161,12 @@ const UrlImage = React.memo(
|
|||
|
||||
const Fields = React.memo(
|
||||
({ attachment, theme, getCustomEmoji }: { attachment: IAttachment; theme: string; getCustomEmoji: TGetCustomEmoji }) => {
|
||||
const { baseUrl, user } = useContext(MessageContext);
|
||||
|
||||
if (!attachment.fields) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { baseUrl, user } = useContext(MessageContext);
|
||||
return (
|
||||
<View style={styles.fieldsContainer}>
|
||||
{attachment.fields.map(field => (
|
||||
|
@ -187,13 +192,12 @@ const Reply = React.memo(
|
|||
({ attachment, timeFormat, index, getCustomEmoji }: IMessageReply) => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const { theme } = useTheme();
|
||||
const { baseUrl, user, jumpToMessage } = useContext(MessageContext);
|
||||
|
||||
if (!attachment) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { baseUrl, user, jumpToMessage } = useContext(MessageContext);
|
||||
|
||||
const onPress = async () => {
|
||||
let url = attachment.title_link || attachment.author_link;
|
||||
if (attachment.message_link) {
|
||||
|
|
|
@ -12,12 +12,12 @@ import { useTheme } from '../../theme';
|
|||
const Thread = React.memo(
|
||||
({ msg, tcount, tlm, isThreadRoom, id }: IMessageThread) => {
|
||||
const { theme } = useTheme();
|
||||
const { threadBadgeColor, toggleFollowThread, user, replies } = useContext(MessageContext);
|
||||
|
||||
if (!tlm || isThreadRoom || tcount === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { threadBadgeColor, toggleFollowThread, user, replies } = useContext(MessageContext);
|
||||
return (
|
||||
<View style={styles.buttonContainer}>
|
||||
<View style={[styles.button, { backgroundColor: themes[theme].tintColor }]} testID={`message-thread-button-${msg}`}>
|
||||
|
|
|
@ -53,10 +53,12 @@ const styles = StyleSheet.create({
|
|||
|
||||
const UrlImage = React.memo(
|
||||
({ image }: { image: string }) => {
|
||||
const { baseUrl, user } = useContext(MessageContext);
|
||||
|
||||
if (!image) {
|
||||
return null;
|
||||
}
|
||||
const { baseUrl, user } = useContext(MessageContext);
|
||||
|
||||
image = image.includes('http') ? image : `${baseUrl}/${image}?rc_uid=${user.id}&rc_token=${user.token}`;
|
||||
return <FastImage source={{ uri: image }} style={styles.image} resizeMode={FastImage.resizeMode.cover} />;
|
||||
},
|
||||
|
|
|
@ -57,9 +57,10 @@ interface IMessageUser {
|
|||
|
||||
const User = React.memo(
|
||||
({ isHeader, useRealName, author, alias, ts, timeFormat, hasError, navToRoomInfo, type, ...props }: IMessageUser) => {
|
||||
const { user } = useContext(MessageContext);
|
||||
const { theme } = useTheme();
|
||||
|
||||
if (isHeader || hasError) {
|
||||
const { user } = useContext(MessageContext);
|
||||
const { theme } = useTheme();
|
||||
const username = (useRealName && author?.name) || author?.username;
|
||||
const aliasUsername = alias ? (
|
||||
<Text style={[styles.alias, { color: themes[theme].auxiliaryText }]}> @{username}</Text>
|
||||
|
|
|
@ -6,7 +6,7 @@ import Message from './Message';
|
|||
import MessageContext from './Context';
|
||||
import debounce from '../../utils/debounce';
|
||||
import { SYSTEM_MESSAGES, getMessageTranslation } from './utils';
|
||||
import { useTheme, withTheme } from '../../theme';
|
||||
import { withTheme } from '../../theme';
|
||||
import openLink from '../../utils/openLink';
|
||||
import { TGetCustomEmoji } from '../../definitions/IEmoji';
|
||||
import { IAttachment, TAnyMessageModel } from '../../definitions';
|
||||
|
@ -57,6 +57,7 @@ interface IMessageContainerProps {
|
|||
toggleFollowThread?: (isFollowingThread: boolean, tmid?: string) => Promise<void>;
|
||||
jumpToMessage?: (link: string) => void;
|
||||
onPress?: () => void;
|
||||
theme: string;
|
||||
}
|
||||
|
||||
interface IMessageContainerState {
|
||||
|
@ -292,8 +293,7 @@ class MessageContainer extends React.Component<IMessageContainerProps, IMessageC
|
|||
};
|
||||
|
||||
onLinkPress = (link: string): void => {
|
||||
const { theme } = useTheme();
|
||||
const { item, jumpToMessage } = this.props;
|
||||
const { item, jumpToMessage, theme } = this.props;
|
||||
const isMessageLink = item?.attachments?.findIndex((att: IAttachment) => att?.message_link === link) !== -1;
|
||||
if (isMessageLink && jumpToMessage) {
|
||||
return jumpToMessage(link);
|
||||
|
|
|
@ -20,16 +20,20 @@ interface IOmnichannelStatus {
|
|||
}
|
||||
|
||||
const OmnichannelStatus = memo(({ searching, goQueue, queueSize, inquiryEnabled, user }: IOmnichannelStatus) => {
|
||||
if (searching || !(RocketChat.isOmnichannelModuleAvailable() && user?.roles?.includes('livechat-agent'))) {
|
||||
return null;
|
||||
}
|
||||
const { theme } = useTheme();
|
||||
const [status, setStatus] = useState(isOmnichannelStatusAvailable(user));
|
||||
const [status, setStatus] = useState<boolean>(false);
|
||||
const canUseOmnichannel = RocketChat.isOmnichannelModuleAvailable() && user?.roles?.includes('livechat-agent');
|
||||
|
||||
useEffect(() => {
|
||||
setStatus(isOmnichannelStatusAvailable(user));
|
||||
if (canUseOmnichannel) {
|
||||
setStatus(isOmnichannelStatusAvailable(user));
|
||||
}
|
||||
}, [user.statusLivechat]);
|
||||
|
||||
if (searching || !canUseOmnichannel) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const toggleLivechat = async () => {
|
||||
try {
|
||||
setStatus(v => !v);
|
||||
|
|
|
@ -6,7 +6,7 @@ import { getDeviceToken } from '../../notifications/push';
|
|||
import { extractHostname } from '../../utils/server';
|
||||
import { BASIC_AUTH_KEY } from '../../utils/fetch';
|
||||
import database, { getDatabase } from '../database';
|
||||
import { useSsl } from '../../utils/url';
|
||||
import { isSsl } from '../../utils/url';
|
||||
import log from '../../utils/log';
|
||||
import { ICertificate, IRocketChat } from '../../definitions';
|
||||
import sdk from '../services/sdk';
|
||||
|
@ -80,7 +80,7 @@ export async function removeServer({ server }: { server: string }): Promise<void
|
|||
if (userId) {
|
||||
const resume = UserPreferences.getString(`${RocketChat.TOKEN_KEY}-${userId}`);
|
||||
|
||||
const sdk = new RocketchatClient({ host: server, protocol: 'ddp', useSsl: useSsl(server) });
|
||||
const sdk = new RocketchatClient({ host: server, protocol: 'ddp', useSsl: isSsl(server) });
|
||||
await sdk.login({ resume });
|
||||
|
||||
const token = getDeviceToken();
|
||||
|
|
|
@ -760,7 +760,7 @@ export const validateInviteToken = (token: string): any =>
|
|||
// @ts-ignore
|
||||
sdk.post('validateInviteToken', { token });
|
||||
|
||||
export const useInviteToken = (token: string): any =>
|
||||
export const inviteToken = (token: string): any =>
|
||||
// RC 2.4.0
|
||||
// TODO: missing definitions from server
|
||||
// @ts-ignore
|
||||
|
|
|
@ -3,7 +3,7 @@ import EJSON from 'ejson';
|
|||
import isEmpty from 'lodash/isEmpty';
|
||||
|
||||
import { twoFactor } from '../../utils/twoFactor';
|
||||
import { useSsl } from '../../utils/url';
|
||||
import { isSsl } from '../../utils/url';
|
||||
import { store as reduxStore } from '../store/auxStore';
|
||||
import { Serialized, MatchPathPattern, OperationParams, PathFor, ResultFor } from '../../definitions/rest/helpers';
|
||||
|
||||
|
@ -14,7 +14,7 @@ class Sdk {
|
|||
|
||||
private initializeSdk(server: string): typeof Rocketchat {
|
||||
// The app can't reconnect if reopen interval is 5s while in development
|
||||
return new Rocketchat({ host: server, protocol: 'ddp', useSsl: useSsl(server), reopen: __DEV__ ? 20000 : 5000 });
|
||||
return new Rocketchat({ host: server, protocol: 'ddp', useSsl: isSsl(server), reopen: __DEV__ ? 20000 : 5000 });
|
||||
}
|
||||
|
||||
// TODO: We need to stop returning the SDK after all methods are dehydrated
|
||||
|
|
|
@ -16,7 +16,7 @@ const handleRequest = function* handleRequest({ token }) {
|
|||
return;
|
||||
}
|
||||
|
||||
const result = yield RocketChat.useInviteToken(token);
|
||||
const result = yield RocketChat.inviteToken(token);
|
||||
if (!result.success) {
|
||||
yield put(inviteLinksFailure());
|
||||
return;
|
||||
|
|
|
@ -11,5 +11,5 @@ export const isValidURL = (url: string): boolean => {
|
|||
return !!pattern.test(url);
|
||||
};
|
||||
|
||||
// Use useSsl: false only if server url starts with http://
|
||||
export const useSsl = (url: string): boolean => !/http:\/\//.test(url);
|
||||
// Use checkUseSsl: false only if server url starts with http://
|
||||
export const isSsl = (url: string): boolean => !/http:\/\//.test(url);
|
||||
|
|
|
@ -201,6 +201,7 @@ class MessagesView extends React.Component<IMessagesViewProps, any> {
|
|||
renderItem: (item: any) => (
|
||||
<Message
|
||||
{...renderItemCommonProps(item)}
|
||||
theme={theme}
|
||||
item={{
|
||||
...item,
|
||||
u: item.user,
|
||||
|
|
|
@ -40,6 +40,8 @@ const LeftButtons = ({
|
|||
goRoomActionsView,
|
||||
isMasterDetail
|
||||
}: ILeftButtonsProps): React.ReactElement | null => {
|
||||
const onPress = useCallback(() => goRoomActionsView(), []);
|
||||
|
||||
if (!isMasterDetail || tmid) {
|
||||
const onPress = () => navigation.goBack();
|
||||
let label = ' ';
|
||||
|
@ -61,7 +63,6 @@ const LeftButtons = ({
|
|||
/>
|
||||
);
|
||||
}
|
||||
const onPress = useCallback(() => goRoomActionsView(), []);
|
||||
|
||||
if (baseUrl && userId && token) {
|
||||
return <Avatar text={title} size={30} type={t} style={styles.avatar} onPress={onPress} />;
|
||||
|
|
|
@ -1144,7 +1144,8 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
|
|||
|
||||
renderItem = (item: TAnyMessageModel, previousItem: TAnyMessageModel, highlightedMessage?: string) => {
|
||||
const { room, lastOpen, canAutoTranslate } = this.state;
|
||||
const { user, Message_GroupingPeriod, Message_TimeFormat, useRealName, baseUrl, Message_Read_Receipt_Enabled } = this.props;
|
||||
const { user, Message_GroupingPeriod, Message_TimeFormat, useRealName, baseUrl, Message_Read_Receipt_Enabled, theme } =
|
||||
this.props;
|
||||
let dateSeparator = null;
|
||||
let showUnreadSeparator = false;
|
||||
|
||||
|
@ -1207,6 +1208,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
|
|||
toggleFollowThread={this.toggleFollowThread}
|
||||
jumpToMessage={this.jumpToMessageByUrl}
|
||||
highlighted={highlightedMessage === item.id}
|
||||
theme={theme}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -20,12 +20,12 @@ interface IRoomListHeader {
|
|||
|
||||
const ListHeader = React.memo(
|
||||
({ searching, goEncryption, goQueue, queueSize, inquiryEnabled, encryptionBanner, user }: IRoomListHeader) => {
|
||||
const { theme } = useTheme();
|
||||
|
||||
if (searching) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { theme } = useTheme();
|
||||
|
||||
return (
|
||||
<>
|
||||
{encryptionBanner ? (
|
||||
|
|
|
@ -174,6 +174,7 @@
|
|||
"eslint-plugin-jest": "24.7.0",
|
||||
"eslint-plugin-jsx-a11y": "6.3.1",
|
||||
"eslint-plugin-react": "7.20.3",
|
||||
"eslint-plugin-react-hooks": "^4.4.0",
|
||||
"eslint-plugin-react-native": "3.8.1",
|
||||
"husky": "^6.0.0",
|
||||
"identity-obj-proxy": "^3.0.0",
|
||||
|
|
|
@ -8570,6 +8570,11 @@ eslint-plugin-jsx-a11y@6.3.1:
|
|||
jsx-ast-utils "^2.4.1"
|
||||
language-tags "^1.0.5"
|
||||
|
||||
eslint-plugin-react-hooks@^4.4.0:
|
||||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.4.0.tgz#71c39e528764c848d8253e1aa2c7024ed505f6c4"
|
||||
integrity sha512-U3RVIfdzJaeKDQKEJbz5p3NW8/L80PCATJAfuojwbaEL+gBjfGdhUcGde+WGUW46Q5sr/NgxevsIiDtNXrvZaQ==
|
||||
|
||||
eslint-plugin-react-native-globals@^0.1.1:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-react-native-globals/-/eslint-plugin-react-native-globals-0.1.2.tgz#ee1348bc2ceb912303ce6bdbd22e2f045ea86ea2"
|
||||
|
|
Loading…
Reference in New Issue