diff --git a/app/containers/ActivityIndicator.tsx b/app/containers/ActivityIndicator.tsx
index 50a60f0c3..e2eb33926 100644
--- a/app/containers/ActivityIndicator.tsx
+++ b/app/containers/ActivityIndicator.tsx
@@ -3,7 +3,7 @@ import { ActivityIndicator, ActivityIndicatorProps, StyleSheet } from 'react-nat
import { themes } from '../constants/colors';
interface IActivityIndicator extends ActivityIndicatorProps{
- theme?: 'light' | 'dark' | 'black',
+ theme?: 'light' | 'dark' | 'black' | string,
absolute?: boolean,
props?: object
}
diff --git a/app/containers/message/Attachments.tsx b/app/containers/message/Attachments.tsx
index 74be12552..07d0c0547 100644
--- a/app/containers/message/Attachments.tsx
+++ b/app/containers/message/Attachments.tsx
@@ -6,7 +6,7 @@ import Audio from './Audio';
import Video from './Video';
import Reply from './Reply';
-interface IMessageAttachments {
+export interface IMessageAttachments {
attachments: any;
timeFormat: string;
showAttachment: Function;
diff --git a/app/containers/message/Audio.js b/app/containers/message/Audio.tsx
similarity index 84%
rename from app/containers/message/Audio.js
rename to app/containers/message/Audio.tsx
index e22dff408..9bf783ff8 100644
--- a/app/containers/message/Audio.js
+++ b/app/containers/message/Audio.tsx
@@ -1,8 +1,5 @@
import React from 'react';
-import PropTypes from 'prop-types';
-import {
- View, StyleSheet, Text, Easing
-} from 'react-native';
+import { View, StyleSheet, Text, Easing } from 'react-native';
import { Audio } from 'expo-av';
import Slider from '@react-native-community/slider';
import moment from 'moment';
@@ -19,6 +16,30 @@ import MessageContext from './Context';
import ActivityIndicator from '../ActivityIndicator';
import { withDimensions } from '../../dimensions';
+type TButton = {
+ loading: boolean;
+ paused: boolean;
+ theme: string;
+ onPress: Function;
+};
+
+interface IMessageAudioProps {
+ file: {
+ audio_url: string;
+ description: string;
+ };
+ theme: string;
+ getCustomEmoji: Function;
+ scale: number;
+}
+
+interface IMessageAudioState {
+ loading: boolean,
+ currentTime: number,
+ duration: number,
+ paused: boolean
+}
+
const mode = {
allowsRecordingIOS: false,
playsInSilentModeIOS: true,
@@ -57,19 +78,17 @@ const styles = StyleSheet.create({
}
});
-const formatTime = seconds => moment.utc(seconds * 1000).format('mm:ss');
-const BUTTON_HIT_SLOP = {
- top: 12, right: 12, bottom: 12, left: 12
-};
+const formatTime = (seconds: number) => moment.utc(seconds * 1000).format('mm:ss');
+
+const BUTTON_HIT_SLOP = { top: 12, right: 12, bottom: 12, left: 12 };
+
const sliderAnimationConfig = {
duration: 250,
easing: Easing.linear,
delay: 0
};
-const Button = React.memo(({
- loading, paused, onPress, theme
-}) => (
+const Button = React.memo(({ loading, paused, onPress, theme }: TButton) => (
));
-Button.propTypes = {
- loading: PropTypes.bool,
- paused: PropTypes.bool,
- theme: PropTypes.string,
- onPress: PropTypes.func
-};
Button.displayName = 'MessageAudioButton';
-class MessageAudio extends React.Component {
+class MessageAudio extends React.Component {
static contextType = MessageContext;
+ private sound: any;
- static propTypes = {
- file: PropTypes.object.isRequired,
- theme: PropTypes.string,
- getCustomEmoji: PropTypes.func,
- scale: PropTypes.number
- }
-
- constructor(props) {
+ constructor(props: IMessageAudioProps) {
super(props);
this.state = {
loading: false,
@@ -133,7 +140,7 @@ class MessageAudio extends React.Component {
this.setState({ loading: false });
}
- shouldComponentUpdate(nextProps, nextState) {
+ shouldComponentUpdate(nextProps: any, nextState: any) {
const {
currentTime, duration, paused, loading
} = this.state;
@@ -176,7 +183,7 @@ class MessageAudio extends React.Component {
}
}
- onPlaybackStatusUpdate = (status) => {
+ onPlaybackStatusUpdate = (status: any) => {
if (status) {
this.onLoad(status);
this.onProgress(status);
@@ -184,12 +191,12 @@ class MessageAudio extends React.Component {
}
}
- onLoad = (data) => {
+ onLoad = (data: any) => {
const duration = data.durationMillis / 1000;
this.setState({ duration: duration > 0 ? duration : 0 });
}
- onProgress = (data) => {
+ onProgress = (data: any) => {
const { duration } = this.state;
const currentTime = data.positionMillis / 1000;
if (currentTime <= duration) {
@@ -197,7 +204,7 @@ class MessageAudio extends React.Component {
}
}
- onEnd = async(data) => {
+ onEnd = async(data: any) => {
if (data.didJustFinish) {
try {
await this.sound.stopAsync();
@@ -232,7 +239,7 @@ class MessageAudio extends React.Component {
}
}
- onValueChange = async(value) => {
+ onValueChange = async(value: any) => {
try {
this.setState({ currentTime: value });
await this.sound.setPositionAsync(value * 1000);
@@ -275,10 +282,12 @@ class MessageAudio extends React.Component {
minimumTrackTintColor={themes[theme].tintColor}
maximumTrackTintColor={themes[theme].auxiliaryText}
onValueChange={this.onValueChange}
+ /*@ts-ignore*/
thumbImage={isIOS && { uri: 'audio_thumb', scale }}
/>
{this.duration}
+ {/*@ts-ignore*/}
>
);
diff --git a/app/containers/message/Blocks.ts b/app/containers/message/Blocks.ts
index 62b1f2d22..5f22d9ca9 100644
--- a/app/containers/message/Blocks.ts
+++ b/app/containers/message/Blocks.ts
@@ -1,7 +1,7 @@
import React from 'react';
import { messageBlockWithContext } from '../UIKit/MessageBlock';
-interface IMessageBlocks {
+export interface IMessageBlocks {
blocks: any;
id: string;
rid: string;
diff --git a/app/containers/message/Broadcast.js b/app/containers/message/Broadcast.tsx
similarity index 84%
rename from app/containers/message/Broadcast.js
rename to app/containers/message/Broadcast.tsx
index 58de1d0dc..106ed8058 100644
--- a/app/containers/message/Broadcast.js
+++ b/app/containers/message/Broadcast.tsx
@@ -1,6 +1,5 @@
import React, { useContext } from 'react';
import { View, Text } from 'react-native';
-import PropTypes from 'prop-types';
import Touchable from './Touchable';
import { CustomIcon } from '../../lib/Icons';
@@ -10,9 +9,15 @@ import I18n from '../../i18n';
import { themes } from '../../constants/colors';
import MessageContext from './Context';
-const Broadcast = React.memo(({
- author, broadcast, theme
-}) => {
+export interface IMessageBroadcast {
+ author: {
+ _id: string
+ };
+ broadcast: boolean;
+ theme: string
+}
+
+const Broadcast = React.memo(({ author, broadcast, theme }: IMessageBroadcast) => {
const { user, replyBroadcast } = useContext(MessageContext);
const isOwn = author._id === user.id;
if (broadcast && !isOwn) {
@@ -36,11 +41,6 @@ const Broadcast = React.memo(({
return null;
});
-Broadcast.propTypes = {
- author: PropTypes.object,
- broadcast: PropTypes.bool,
- theme: PropTypes.string
-};
Broadcast.displayName = 'MessageBroadcast';
export default Broadcast;
diff --git a/app/containers/message/CallButton.tsx b/app/containers/message/CallButton.tsx
index a0ba95d32..19ee3ad95 100644
--- a/app/containers/message/CallButton.tsx
+++ b/app/containers/message/CallButton.tsx
@@ -8,7 +8,7 @@ import I18n from '../../i18n';
import { CustomIcon } from '../../lib/Icons';
import { themes } from '../../constants/colors';
-interface IMessageCallButton {
+export interface IMessageCallButton {
theme: string;
callJitsi: Function;
}
diff --git a/app/containers/message/Content.js b/app/containers/message/Content.tsx
similarity index 82%
rename from app/containers/message/Content.js
rename to app/containers/message/Content.tsx
index 90af48acd..2f1f542f0 100644
--- a/app/containers/message/Content.js
+++ b/app/containers/message/Content.tsx
@@ -1,6 +1,5 @@
import React, { useContext } from 'react';
import { Text, View } from 'react-native';
-import PropTypes from 'prop-types';
import { dequal } from 'dequal';
import I18n from '../../i18n';
@@ -12,9 +11,29 @@ import { themes } from '../../constants/colors';
import MessageContext from './Context';
import Encrypted from './Encrypted';
import { E2E_MESSAGE_TYPE } from '../../lib/encryption/constants';
+import {TChannel} from "../markdown/Hashtag";
-const Content = React.memo((props) => {
+export interface IMessageContent {
+ isTemp: boolean;
+ isInfo: boolean;
+ tmid: string;
+ isThreadRoom: boolean;
+ msg: string;
+ theme: string;
+ isEdited: boolean;
+ isEncrypted: boolean;
+ getCustomEmoji: Function;
+ channels: TChannel[];
+ mentions: object[];
+ navToRoomInfo: Function;
+ useRealName: boolean;
+ isIgnored: boolean;
+ type: string;
+}
+
+const Content = React.memo((props: IMessageContent) => {
if (props.isInfo) {
+ // @ts-ignore
const infoMessage = getInfoMessage({ ...props });
const renderMessageContent = (
@@ -37,7 +56,7 @@ const Content = React.memo((props) => {
return renderMessageContent;
}
- const isPreview = props.tmid && !props.isThreadRoom;
+ const isPreview: any = props.tmid && !props.isThreadRoom;
let content = null;
if (props.tmid && !props.msg) {
@@ -47,6 +66,7 @@ const Content = React.memo((props) => {
} else {
const { baseUrl, user, onLinkPress } = useContext(MessageContext);
content = (
+ // @ts-ignore
{
return true;
});
-Content.propTypes = {
- isTemp: PropTypes.bool,
- isInfo: PropTypes.bool,
- tmid: PropTypes.string,
- isThreadRoom: PropTypes.bool,
- msg: PropTypes.string,
- theme: PropTypes.string,
- isEdited: PropTypes.bool,
- isEncrypted: PropTypes.bool,
- getCustomEmoji: PropTypes.func,
- channels: PropTypes.oneOfType([PropTypes.array, PropTypes.object]),
- mentions: PropTypes.oneOfType([PropTypes.array, PropTypes.object]),
- navToRoomInfo: PropTypes.func,
- useRealName: PropTypes.bool,
- isIgnored: PropTypes.bool,
- type: PropTypes.string
-};
Content.displayName = 'MessageContent';
export default Content;
diff --git a/app/containers/message/Context.js b/app/containers/message/Context.js
deleted file mode 100644
index 407904b4e..000000000
--- a/app/containers/message/Context.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import React from 'react';
-
-const MessageContext = React.createContext();
-export default MessageContext;
diff --git a/app/containers/message/Context.ts b/app/containers/message/Context.ts
new file mode 100644
index 000000000..eee35a6c7
--- /dev/null
+++ b/app/containers/message/Context.ts
@@ -0,0 +1,5 @@
+import React from 'react';
+
+// @ts-ignore
+const MessageContext = React.createContext();
+export default MessageContext;
diff --git a/app/containers/message/Discussion.tsx b/app/containers/message/Discussion.tsx
index 7d7d207a9..34a88263d 100644
--- a/app/containers/message/Discussion.tsx
+++ b/app/containers/message/Discussion.tsx
@@ -11,7 +11,7 @@ import { themes } from '../../constants/colors';
import MessageContext from './Context';
import { formatDateThreads } from '../../utils/room';
-interface IMessageDiscussion {
+export interface IMessageDiscussion {
msg: string;
dcount: number;
dlm: string;
diff --git a/app/containers/message/Message.js b/app/containers/message/Message.tsx
similarity index 64%
rename from app/containers/message/Message.js
rename to app/containers/message/Message.tsx
index 4bc03c000..2870ff4a5 100644
--- a/app/containers/message/Message.js
+++ b/app/containers/message/Message.tsx
@@ -1,5 +1,4 @@
import React, { useContext } from 'react';
-import PropTypes from 'prop-types';
import { View } from 'react-native';
import Touchable from 'react-native-platform-touchable';
@@ -7,21 +6,59 @@ import MessageContext from './Context';
import User from './User';
import styles from './styles';
-import RepliedThread from './RepliedThread';
-import MessageAvatar from './MessageAvatar';
-import Attachments from './Attachments';
+import RepliedThread, {IMessageRepliedThread} from './RepliedThread';
+import MessageAvatar, {IMessageAvatar} from './MessageAvatar';
+import Attachments, {IMessageAttachments} from './Attachments';
import Urls from './Urls';
-import Thread from './Thread';
-import Blocks from './Blocks';
+import Thread, {IMessageThread} from './Thread';
+import Blocks, {IMessageBlocks} from './Blocks';
import Reactions from './Reactions';
-import Broadcast from './Broadcast';
-import Discussion from './Discussion';
-import Content from './Content';
+import Broadcast, {IMessageBroadcast} from './Broadcast';
+import Discussion, {IMessageDiscussion} from './Discussion';
+import Content, {IMessageContent} from './Content';
import ReadReceipt from './ReadReceipt';
-import CallButton from './CallButton';
+import CallButton, {IMessageCallButton} from './CallButton';
import { themes } from '../../constants/colors';
-const MessageInner = React.memo((props) => {
+
+type TMessageInner = {
+ type: string;
+ blocks: [];
+} & IMessageDiscussion & IMessageContent & IMessageCallButton & IMessageBlocks
+ & IMessageThread & IMessageAttachments & IMessageBroadcast;
+
+type TMessage = {
+ isThreadReply: boolean;
+ isThreadSequential: boolean;
+ isInfo: boolean;
+ isTemp: boolean;
+ isHeader: boolean;
+ hasError: boolean;
+ style: any;
+ onLongPress: Function;
+ isReadReceiptEnabled: boolean;
+ unread: boolean;
+ theme: string;
+ isIgnored: boolean;
+} & IMessageRepliedThread & IMessageAvatar & IMessageContent & TMessageInner;
+
+interface IMessageTouchable {
+ hasError: boolean;
+ isInfo: boolean;
+ isThreadReply: boolean;
+ isTemp: boolean;
+ archived: boolean;
+ highlighted: boolean;
+ theme: string;
+ ts?: any
+ urls?: any;
+ reactions?: any;
+ alias?: any;
+ role?: any;
+ drid?: any;
+}
+
+const MessageInner = React.memo((props: TMessageInner) => {
if (props.type === 'discussion-created') {
return (
<>
@@ -63,7 +100,7 @@ const MessageInner = React.memo((props) => {
});
MessageInner.displayName = 'MessageInner';
-const Message = React.memo((props) => {
+const Message = React.memo((props: TMessage) => {
if (props.isThreadReply || props.isThreadSequential || props.isInfo || props.isIgnored) {
const thread = props.isThreadReply ? : null;
return (
@@ -107,7 +144,7 @@ const Message = React.memo((props) => {
});
Message.displayName = 'Message';
-const MessageTouchable = React.memo((props) => {
+const MessageTouchable = React.memo((props: IMessageTouchable & TMessage) => {
if (props.hasError) {
return (
@@ -129,36 +166,7 @@ const MessageTouchable = React.memo((props) => {
);
});
+
MessageTouchable.displayName = 'MessageTouchable';
-MessageTouchable.propTypes = {
- hasError: PropTypes.bool,
- isInfo: PropTypes.bool,
- isThreadReply: PropTypes.bool,
- isTemp: PropTypes.bool,
- archived: PropTypes.bool,
- highlighted: PropTypes.bool,
- theme: PropTypes.string
-};
-
-Message.propTypes = {
- isThreadReply: PropTypes.bool,
- isThreadSequential: PropTypes.bool,
- isInfo: PropTypes.bool,
- isTemp: PropTypes.bool,
- isHeader: PropTypes.bool,
- hasError: PropTypes.bool,
- style: PropTypes.any,
- onLongPress: PropTypes.func,
- isReadReceiptEnabled: PropTypes.bool,
- unread: PropTypes.bool,
- theme: PropTypes.string,
- isIgnored: PropTypes.bool
-};
-
-MessageInner.propTypes = {
- type: PropTypes.string,
- blocks: PropTypes.array
-};
-
export default MessageTouchable;
diff --git a/app/containers/message/MessageAvatar.tsx b/app/containers/message/MessageAvatar.tsx
index 26a296993..cb7f71800 100644
--- a/app/containers/message/MessageAvatar.tsx
+++ b/app/containers/message/MessageAvatar.tsx
@@ -4,7 +4,7 @@ import Avatar from '../Avatar';
import styles from './styles';
import MessageContext from './Context';
-interface IMessageAvatar {
+export interface IMessageAvatar {
isHeader: boolean;
avatar: string;
emoji: string;
@@ -12,7 +12,7 @@ interface IMessageAvatar {
username: string
_id: string;
};
- small: boolean;
+ small?: boolean;
navToRoomInfo: Function;
getCustomEmoji(): void;
theme: string;
diff --git a/app/containers/message/RepliedThread.tsx b/app/containers/message/RepliedThread.tsx
index d91c3f008..4e832a961 100644
--- a/app/containers/message/RepliedThread.tsx
+++ b/app/containers/message/RepliedThread.tsx
@@ -7,7 +7,7 @@ import { themes } from '../../constants/colors';
import I18n from '../../i18n';
import Markdown from '../markdown';
-interface IMessageRepliedThread {
+export interface IMessageRepliedThread {
tmid: string;
tmsg: string;
id: string;
diff --git a/app/containers/message/Thread.tsx b/app/containers/message/Thread.tsx
index adbcd89e5..361a51805 100644
--- a/app/containers/message/Thread.tsx
+++ b/app/containers/message/Thread.tsx
@@ -7,7 +7,7 @@ import MessageContext from './Context';
import ThreadDetails from '../ThreadDetails';
import I18n from '../../i18n';
-interface IMessageThread {
+export interface IMessageThread {
msg: string;
tcount: number;
theme: string;
diff --git a/app/containers/message/index.js b/app/containers/message/index.tsx
similarity index 76%
rename from app/containers/message/index.js
rename to app/containers/message/index.tsx
index 467c634a6..9e92ccb63 100644
--- a/app/containers/message/index.js
+++ b/app/containers/message/index.tsx
@@ -11,75 +11,62 @@ import messagesStatus from '../../constants/messagesStatus';
import { withTheme } from '../../theme';
import openLink from '../../utils/openLink';
-class MessageContainer extends React.Component {
- static propTypes = {
- item: PropTypes.object.isRequired,
- user: PropTypes.shape({
- id: PropTypes.string.isRequired,
- username: PropTypes.string.isRequired,
- token: PropTypes.string.isRequired
- }),
- rid: PropTypes.string,
- timeFormat: PropTypes.string,
- style: PropTypes.any,
- archived: PropTypes.bool,
- broadcast: PropTypes.bool,
- previousItem: PropTypes.object,
- baseUrl: PropTypes.string,
- Message_GroupingPeriod: PropTypes.number,
- isReadReceiptEnabled: PropTypes.bool,
- isThreadRoom: PropTypes.bool,
- useRealName: PropTypes.bool,
- autoTranslateRoom: PropTypes.bool,
- autoTranslateLanguage: PropTypes.string,
- status: PropTypes.number,
- isIgnored: PropTypes.bool,
- highlighted: PropTypes.bool,
- getCustomEmoji: PropTypes.func,
- onLongPress: PropTypes.func,
- onReactionPress: PropTypes.func,
- onEncryptedPress: PropTypes.func,
- onDiscussionPress: PropTypes.func,
- onThreadPress: PropTypes.func,
- errorActionsShow: PropTypes.func,
- replyBroadcast: PropTypes.func,
- reactionInit: PropTypes.func,
- fetchThreadName: PropTypes.func,
- showAttachment: PropTypes.func,
- onReactionLongPress: PropTypes.func,
- navToRoomInfo: PropTypes.func,
- callJitsi: PropTypes.func,
- blockAction: PropTypes.func,
- theme: PropTypes.string,
- threadBadgeColor: PropTypes.string,
- toggleFollowThread: PropTypes.func,
- jumpToMessage: PropTypes.func,
- onPress: PropTypes.func
- }
+interface IMessageContainerProps {
+ item: any;
+ user: {
+ id: string;
+ username: string;
+ token: string;
+ };
+ rid: string;
+ timeFormat: string;
+ style: any;
+ archived: boolean;
+ broadcast: boolean;
+ previousItem: {
+ ts: any;
+ u: any;
+ groupable: any;
+ id: any;
+ tmid: any;
+ status: any
+ };
+ baseUrl: string;
+ Message_GroupingPeriod: number;
+ isReadReceiptEnabled: boolean;
+ isThreadRoom: boolean;
+ useRealName: boolean;
+ autoTranslateRoom: boolean;
+ autoTranslateLanguage: string;
+ status: number;
+ isIgnored: boolean;
+ highlighted: boolean;
+ getCustomEmoji(): void;
+ onLongPress: Function;
+ onReactionPress: Function;
+ onEncryptedPress: Function;
+ onDiscussionPress: Function;
+ onThreadPress: Function;
+ errorActionsShow: Function;
+ replyBroadcast: Function;
+ reactionInit: Function;
+ fetchThreadName: Function;
+ showAttachment: Function;
+ onReactionLongPress: Function;
+ navToRoomInfo: Function;
+ callJitsi: Function;
+ blockAction: Function;
+ theme: string;
+ threadBadgeColor: string;
+ toggleFollowThread: Function;
+ jumpToMessage: Function;
+ onPress: Function;
+}
- static defaultProps = {
- getCustomEmoji: () => {},
- onLongPress: () => {},
- onReactionPress: () => {},
- onEncryptedPress: () => {},
- onDiscussionPress: () => {},
- onThreadPress: () => {},
- errorActionsShow: () => {},
- replyBroadcast: () => {},
- reactionInit: () => {},
- fetchThreadName: () => {},
- showAttachment: () => {},
- onReactionLongPress: () => {},
- navToRoomInfo: () => {},
- callJitsi: () => {},
- blockAction: () => {},
- archived: false,
- broadcast: false,
- isIgnored: false,
- theme: 'light'
- }
+class MessageContainer extends React.Component {
state = { isManualUnignored: false };
+ private subscription: any;
componentDidMount() {
const { item } = this.props;
@@ -91,7 +78,7 @@ class MessageContainer extends React.Component {
}
}
- shouldComponentUpdate(nextProps, nextState) {
+ shouldComponentUpdate(nextProps: any, nextState: any) {
const { isManualUnignored } = this.state;
const {
theme, threadBadgeColor, isIgnored, highlighted
@@ -155,7 +142,7 @@ class MessageContainer extends React.Component {
}
}
- onReactionPress = (emoji) => {
+ onReactionPress = (emoji: any) => {
const { onReactionPress, item } = this.props;
if (onReactionPress) {
onReactionPress(emoji, item.id);
@@ -195,9 +182,7 @@ class MessageContainer extends React.Component {
}
get isHeader() {
- const {
- item, previousItem, broadcast, Message_GroupingPeriod
- } = this.props;
+ const { item, previousItem, broadcast, Message_GroupingPeriod } = this.props;
if (this.hasError || (previousItem && previousItem.status === messagesStatus.ERROR)) {
return true;
}
@@ -218,9 +203,7 @@ class MessageContainer extends React.Component {
}
get isThreadReply() {
- const {
- item, previousItem, isThreadRoom
- } = this.props;
+ const { item, previousItem, isThreadRoom } = this.props;
if (isThreadRoom) {
return false;
}
@@ -279,9 +262,9 @@ class MessageContainer extends React.Component {
}
}
- onLinkPress = (link) => {
+ onLinkPress = (link: any) => {
const { item, theme, jumpToMessage } = this.props;
- const isMessageLink = item?.attachments?.findIndex(att => att?.message_link === link) !== -1;
+ const isMessageLink = item?.attachments?.findIndex((att: any) => att?.message_link === link) !== -1;
if (isMessageLink) {
return jumpToMessage(link);
}
@@ -372,6 +355,7 @@ class MessageContainer extends React.Component {
replies
}}
>
+ {/*@ts-ignore*/}