diff --git a/app/presentation/ImageViewer/ImageViewer.ios.tsx b/app/presentation/ImageViewer/ImageViewer.tsx similarity index 100% rename from app/presentation/ImageViewer/ImageViewer.ios.tsx rename to app/presentation/ImageViewer/ImageViewer.tsx diff --git a/app/presentation/ImageViewer/index.ts b/app/presentation/ImageViewer/index.ts index d8ae350b5..bf629ae84 100644 --- a/app/presentation/ImageViewer/index.ts +++ b/app/presentation/ImageViewer/index.ts @@ -1,5 +1,3 @@ -// @ts-ignore -// eslint-disable-next-line import/no-unresolved export * from './ImageViewer'; export * from './types'; export * from './ImageComponent'; diff --git a/app/views/ShareView/Header.js b/app/views/ShareView/Header.tsx similarity index 91% rename from app/views/ShareView/Header.js rename to app/views/ShareView/Header.tsx index a52fbf453..41e5339e1 100644 --- a/app/views/ShareView/Header.js +++ b/app/views/ShareView/Header.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import PropTypes from 'prop-types'; import { StyleSheet, Text, View } from 'react-native'; import I18n from '../../i18n'; @@ -35,7 +34,13 @@ const styles = StyleSheet.create({ } }); -const Header = React.memo(({ room, thread, theme }) => { +interface IHeader { + room: { prid?: string; t?: string }; + thread: { id?: string }; + theme: string; +} + +const Header = React.memo(({ room, thread, theme }: IHeader) => { let type; if (thread?.id) { type = 'thread'; @@ -88,10 +93,5 @@ const Header = React.memo(({ room, thread, theme }) => { ); }); -Header.propTypes = { - room: PropTypes.object, - thread: PropTypes.object, - theme: PropTypes.string -}; export default withTheme(Header); diff --git a/app/views/ShareView/Preview.js b/app/views/ShareView/Preview.tsx similarity index 87% rename from app/views/ShareView/Preview.js rename to app/views/ShareView/Preview.tsx index d559640f4..e7600dda6 100644 --- a/app/views/ShareView/Preview.js +++ b/app/views/ShareView/Preview.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import PropTypes from 'prop-types'; import { Video } from 'expo-av'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { ScrollView, StyleSheet, Text } from 'react-native'; @@ -15,6 +14,7 @@ import I18n from '../../i18n'; import { isAndroid } from '../../utils/deviceInfo'; import { allowPreview } from './utils'; import { THUMBS_HEIGHT } from './constants'; +import { IAttachment, IUseDimensions } from './interfaces'; const MESSAGEBOX_HEIGHT = 56; @@ -35,7 +35,17 @@ const styles = StyleSheet.create({ } }); -const IconPreview = React.memo(({ iconName, title, description, theme, width, height, danger }) => ( +interface IIconPreview { + iconName: string; + title: string; + description?: string; + theme: string; + width: number; + height: number; + danger?: boolean; +} + +const IconPreview = React.memo(({ iconName, title, description, theme, width, height, danger }: IIconPreview) => ( @@ -45,9 +55,16 @@ const IconPreview = React.memo(({ iconName, title, description, theme, width, he )); -const Preview = React.memo(({ item, theme, isShareExtension, length }) => { +interface IPreview { + item: IAttachment; + theme: string; + isShareExtension: boolean; + length: number; +} + +const Preview = React.memo(({ item, theme, isShareExtension, length }: IPreview) => { const type = item?.mime; - const { width, height } = useDimensions(); + const { width, height } = useDimensions() as IUseDimensions; const { isLandscape } = useOrientation(); const insets = useSafeAreaInsets(); const headerHeight = getHeaderHeight(isLandscape); @@ -111,21 +128,5 @@ const Preview = React.memo(({ item, theme, isShareExtension, length }) => { /> ); }); -Preview.propTypes = { - item: PropTypes.object, - theme: PropTypes.string, - isShareExtension: PropTypes.bool, - length: PropTypes.number -}; - -IconPreview.propTypes = { - iconName: PropTypes.string, - title: PropTypes.string, - description: PropTypes.string, - theme: PropTypes.string, - width: PropTypes.number, - height: PropTypes.number, - danger: PropTypes.bool -}; export default Preview; diff --git a/app/views/ShareView/Thumbs.js b/app/views/ShareView/Thumbs.tsx similarity index 77% rename from app/views/ShareView/Thumbs.js rename to app/views/ShareView/Thumbs.tsx index 758433e3f..da0808cc0 100644 --- a/app/views/ShareView/Thumbs.js +++ b/app/views/ShareView/Thumbs.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import PropTypes from 'prop-types'; import { FlatList, Image, StyleSheet, View } from 'react-native'; import { RectButton, TouchableNativeFeedback, TouchableOpacity } from 'react-native-gesture-handler'; @@ -9,6 +8,7 @@ import { CustomIcon } from '../../lib/Icons'; import { isIOS } from '../../utils/deviceInfo'; import { THUMBS_HEIGHT } from './constants'; import { allowPreview } from './utils'; +import { IAttachment } from './interfaces'; const THUMB_SIZE = 64; @@ -60,22 +60,34 @@ const styles = StyleSheet.create({ } }); -const ThumbButton = isIOS ? TouchableOpacity : TouchableNativeFeedback; +interface IThumbContent { + item: IAttachment; + theme: string; + isShareExtension: boolean; +} -const ThumbContent = React.memo(({ item, theme, isShareExtension }) => { +interface IThumb extends IThumbContent { + onPress(item: IAttachment): void; + onRemove(item: IAttachment): void; +} + +interface IThumbs extends Omit { + attachments: IAttachment[]; +} + +const ThumbContent = React.memo(({ item, theme, isShareExtension }: IThumbContent) => { const type = item?.mime; if (type?.match(/image/)) { // Disallow preview of images too big in order to prevent memory issues on iOS share extension if (allowPreview(isShareExtension, item?.size)) { return ; - } else { - return ( - - - - ); } + return ( + + + + ); } if (type?.match(/video/)) { @@ -85,22 +97,23 @@ const ThumbContent = React.memo(({ item, theme, isShareExtension }) => { ); - } else { - const { uri } = item; - return ( - <> - - - - ); } + const { uri } = item; + return ( + <> + + + + ); } // Multiple files upload of files different than image/video is not implemented, so there's no thumb return null; }); -const Thumb = ({ item, theme, isShareExtension, onPress, onRemove }) => ( +const ThumbButton: typeof React.Component = isIOS ? TouchableOpacity : TouchableNativeFeedback; + +const Thumb = ({ item, theme, isShareExtension, onPress, onRemove }: IThumb) => ( onPress(item)} activeOpacity={0.7}> <> @@ -121,7 +134,7 @@ const Thumb = ({ item, theme, isShareExtension, onPress, onRemove }) => ( ); -const Thumbs = React.memo(({ attachments, theme, isShareExtension, onPress, onRemove }) => { +const Thumbs = React.memo(({ attachments, theme, isShareExtension, onPress, onRemove }: IThumbs) => { if (attachments?.length > 1) { return ( ; + route: RouteProp< + { + ShareView: { + attachments: IAttachment[]; + isShareView?: boolean; + isShareExtension: boolean; + serverInfo: IServer; + text: string; + room: any; + thread: any; // change + }; + }, + 'ShareView' + >; + theme: string; + user: { + id: string; + username: string; + token: string; + }; + server: string; + FileUpload_MediaTypeWhiteList?: number; + FileUpload_MaxFileSize?: number; +} + +interface IMessageBoxShareView { + text: string; + forceUpdate(): void; +} + +class ShareView extends Component { + private messagebox: React.RefObject; + private files: any[]; + private isShareExtension: boolean; + private serverInfo: any; + + constructor(props: IShareViewProps) { super(props); this.messagebox = React.createRef(); this.files = props.route.params?.attachments ?? []; @@ -34,7 +87,7 @@ class ShareView extends Component { this.serverInfo = props.route.params?.serverInfo ?? {}; this.state = { - selected: {}, + selected: {} as IAttachment, loading: false, readOnly: false, attachments: [], @@ -61,7 +114,7 @@ class ShareView extends Component { const { room, thread, readOnly, attachments } = this.state; const { navigation, theme } = this.props; - const options = { + const options: StackNavigationOptions = { headerTitle: () =>
, headerTitleAlign: 'left', headerTintColor: themes[theme].previewTintColor @@ -69,9 +122,7 @@ class ShareView extends Component { // if is share extension show default back button if (!this.isShareExtension) { - options.headerLeft = () => ( - - ); + options.headerLeft = () => ; } if (!attachments.length && !readOnly) { @@ -203,10 +254,10 @@ class ShareView extends Component { } }; - selectFile = item => { + selectFile = (item: IAttachment) => { const { attachments, selected } = this.state; if (attachments.length > 0) { - const { text } = this.messagebox.current; + const text = this.messagebox.current?.text; const newAttachments = attachments.map(att => { if (att.path === selected.path) { att.description = text; @@ -217,7 +268,7 @@ class ShareView extends Component { } }; - removeFile = item => { + removeFile = (item: IAttachment) => { const { selected, attachments } = this.state; let newSelected; if (item.path === selected.path) { @@ -235,7 +286,7 @@ class ShareView extends Component { }); }; - onChangeText = text => { + onChangeText = (text: string) => { this.setState({ text }); }; @@ -318,21 +369,7 @@ class ShareView extends Component { } } -ShareView.propTypes = { - navigation: PropTypes.object, - route: PropTypes.object, - theme: PropTypes.string, - user: PropTypes.shape({ - id: PropTypes.string.isRequired, - username: PropTypes.string.isRequired, - token: PropTypes.string.isRequired - }), - server: PropTypes.string, - FileUpload_MediaTypeWhiteList: PropTypes.string, - FileUpload_MaxFileSize: PropTypes.string -}; - -const mapStateToProps = state => ({ +const mapStateToProps = (state: any) => ({ user: getUserSelector(state), server: state.share.server.server || state.server.server, FileUpload_MediaTypeWhiteList: state.settings.FileUpload_MediaTypeWhiteList, diff --git a/app/views/ShareView/interfaces.ts b/app/views/ShareView/interfaces.ts new file mode 100644 index 000000000..09cb4d9eb --- /dev/null +++ b/app/views/ShareView/interfaces.ts @@ -0,0 +1,33 @@ +export interface IAttachment { + filename: string; + description?: string; + size: number; + mime?: string; + path: string; + canUpload: boolean; + error?: any; + uri: string; +} + +export interface IUseDimensions { + width: number; + height: number; +} + +// TODO: move this to specific folder +export interface IServer { + name: string; + iconURL: string; + useRealName: boolean; + FileUpload_MediaTypeWhiteList: string; + FileUpload_MaxFileSize: number; + roomsUpdatedAt: Date; + version: string; + lastLocalAuthenticatedSession: Date; + autoLock: boolean; + autoLockTime: number | null; + biometry: boolean | null; + uniqueID: string; + enterpriseModules: string; + E2E_Enable: boolean; +} diff --git a/app/views/ShareView/styles.js b/app/views/ShareView/styles.ts similarity index 100% rename from app/views/ShareView/styles.js rename to app/views/ShareView/styles.ts diff --git a/app/views/ShareView/utils.js b/app/views/ShareView/utils.js deleted file mode 100644 index f55cd8356..000000000 --- a/app/views/ShareView/utils.js +++ /dev/null @@ -1,4 +0,0 @@ -import { isAndroid } from '../../utils/deviceInfo'; - -// Limit preview to 3MB on iOS share extension -export const allowPreview = (isShareExtension, size) => isAndroid || !isShareExtension || size < 3000000; diff --git a/app/views/ShareView/utils.ts b/app/views/ShareView/utils.ts new file mode 100644 index 000000000..fa6150411 --- /dev/null +++ b/app/views/ShareView/utils.ts @@ -0,0 +1,5 @@ +import { isAndroid } from '../../utils/deviceInfo'; + +// Limit preview to 3MB on iOS share extension +export const allowPreview = (isShareExtension: boolean, size: number): boolean => + isAndroid || !isShareExtension || size < 3000000;