From 691bf1ef17f799d7c74891d1fe9d8b70c3b48503 Mon Sep 17 00:00:00 2001 From: Gerzon Z Date: Fri, 3 Dec 2021 15:27:57 -0400 Subject: [PATCH] Chore: Migrate react-navigation to TypeScript (#3480) Co-authored-by: AlexAlexandre --- app/AppContainer.tsx | 5 +- app/containers/ActionSheet/Provider.tsx | 2 +- app/containers/EmojiPicker/index.tsx | 5 +- app/containers/LoginServices.tsx | 2 +- app/containers/MessageBox/EmojiKeyboard.tsx | 2 +- app/containers/MessageBox/index.tsx | 2 +- app/containers/SearchBox.tsx | 4 +- app/definitions/IAttachment.ts | 10 + app/definitions/IMessage.ts | 3 + app/definitions/IRocketChatRecord.ts | 4 + app/definitions/IRoom.ts | 27 ++ app/definitions/IServer.ts | 16 + .../ITeam.js => definitions/ITeam.ts} | 0 app/dimensions.tsx | 2 +- app/ee/omnichannel/views/QueueListView.js | 1 + app/lib/rocketchat.js | 2 +- app/navigationTypes.ts | 45 +++ app/share.tsx | 16 +- .../{InsideStack.js => InsideStack.tsx} | 100 +++---- .../{ModalContainer.js => ModalContainer.tsx} | 19 +- .../MasterDetailStack/{index.js => index.tsx} | 70 ++--- app/stacks/MasterDetailStack/types.ts | 203 +++++++++++++ .../{OutsideStack.js => OutsideStack.tsx} | 18 +- app/stacks/types.ts | 275 ++++++++++++++++++ app/theme.tsx | 2 +- app/utils/fileDownload/index.ts | 8 +- app/views/AddChannelTeamView.tsx | 21 +- app/views/AddExistingChannelView.tsx | 7 +- app/views/AdminPanelView/index.tsx | 3 +- app/views/AttachmentView.tsx | 16 +- app/views/AuthenticationWebView.tsx | 14 +- app/views/AutoTranslateView/index.tsx | 16 +- app/views/CreateChannelView.tsx | 9 +- app/views/CreateDiscussionView/index.tsx | 3 +- app/views/CreateDiscussionView/interfaces.ts | 17 +- app/views/DirectoryView/index.tsx | 4 +- app/views/E2EEnterYourPasswordView.tsx | 3 +- app/views/E2EHowItWorksView.tsx | 5 +- app/views/E2ESaveYourPasswordView.tsx | 3 +- app/views/ForgotPasswordView.tsx | 5 +- app/views/ForwardLivechatView.tsx | 5 +- app/views/InviteUsersEditView/index.tsx | 13 +- app/views/InviteUsersView/index.tsx | 11 +- app/views/JitsiMeetView.tsx | 5 +- app/views/LoginView.tsx | 15 +- app/views/MarkdownTableView.tsx | 6 +- app/views/MessagesView/index.tsx | 49 ++-- app/views/NewServerView/index.tsx | 3 +- .../NotificationPreferencesView/index.tsx | 13 +- .../NotificationPreferencesView/options.ts | 2 +- app/views/PickerView.tsx | 32 +- app/views/ProfileView/interfaces.ts | 6 +- app/views/ReadReceiptView/index.tsx | 5 +- app/views/RegisterView.tsx | 5 +- app/views/SearchMessagesView/index.tsx | 36 ++- app/views/SendEmailConfirmationView.tsx | 14 +- app/views/SettingsView/index.tsx | 11 +- app/views/ShareView/index.tsx | 27 +- app/views/ShareView/interfaces.ts | 18 -- app/views/SidebarView/index.tsx | 7 +- .../UserNotificationPreferencesView/index.tsx | 3 +- app/views/UserPreferencesView/index.tsx | 5 +- app/views/WithoutServersView.tsx | 6 +- app/views/WorkspaceView/index.tsx | 8 +- 64 files changed, 901 insertions(+), 373 deletions(-) create mode 100644 app/definitions/IAttachment.ts create mode 100644 app/definitions/IMessage.ts create mode 100644 app/definitions/IRocketChatRecord.ts create mode 100644 app/definitions/IRoom.ts create mode 100644 app/definitions/IServer.ts rename app/{definition/ITeam.js => definitions/ITeam.ts} (100%) create mode 100644 app/navigationTypes.ts rename app/stacks/{InsideStack.js => InsideStack.tsx} (82%) rename app/stacks/MasterDetailStack/{ModalContainer.js => ModalContainer.tsx} (60%) rename app/stacks/MasterDetailStack/{index.js => index.tsx} (87%) create mode 100644 app/stacks/MasterDetailStack/types.ts rename app/stacks/{OutsideStack.js => OutsideStack.tsx} (81%) create mode 100644 app/stacks/types.ts diff --git a/app/AppContainer.tsx b/app/AppContainer.tsx index f7f08bb27..b73aaf8e3 100644 --- a/app/AppContainer.tsx +++ b/app/AppContainer.tsx @@ -3,6 +3,7 @@ import { NavigationContainer } from '@react-navigation/native'; import { createStackNavigator } from '@react-navigation/stack'; import { connect } from 'react-redux'; +import { SetUsernameStackParamList, StackParamList } from './navigationTypes'; import Navigation from './lib/Navigation'; import { defaultHeader, getActiveRouteName, navigationTheme } from './utils/navigation'; import { ROOT_INSIDE, ROOT_LOADING, ROOT_OUTSIDE, ROOT_SET_USERNAME } from './actions/app'; @@ -17,7 +18,7 @@ import { ThemeContext } from './theme'; import { setCurrentScreen } from './utils/log'; // SetUsernameStack -const SetUsername = createStackNavigator(); +const SetUsername = createStackNavigator(); const SetUsernameStack = () => ( @@ -25,7 +26,7 @@ const SetUsernameStack = () => ( ); // App -const Stack = createStackNavigator(); +const Stack = createStackNavigator(); const App = React.memo(({ root, isMasterDetail }: { root: string; isMasterDetail: boolean }) => { if (!root) { return null; diff --git a/app/containers/ActionSheet/Provider.tsx b/app/containers/ActionSheet/Provider.tsx index 0e58ae572..8e786b05f 100644 --- a/app/containers/ActionSheet/Provider.tsx +++ b/app/containers/ActionSheet/Provider.tsx @@ -17,7 +17,7 @@ export const useActionSheet = () => useContext(context); const { Provider, Consumer } = context; -export const withActionSheet =

(Component: React.ComponentType

) => +export const withActionSheet = (Component: any): any => forwardRef((props: any, ref: ForwardedRef) => ( {(contexts: any) => } )); diff --git a/app/containers/EmojiPicker/index.tsx b/app/containers/EmojiPicker/index.tsx index 64f5dbfe3..12217cf95 100644 --- a/app/containers/EmojiPicker/index.tsx +++ b/app/containers/EmojiPicker/index.tsx @@ -31,7 +31,7 @@ interface IEmojiPickerProps { customEmojis?: any; style: object; theme?: string; - onEmojiSelected?: Function; + onEmojiSelected?: ((emoji: any) => void) | ((keyboardId: any, params?: any) => void); tabEmojiStyle?: object; } @@ -201,4 +201,5 @@ const mapStateToProps = (state: any) => ({ customEmojis: state.customEmojis }); -export default connect(mapStateToProps)(withTheme(EmojiPicker)); +// TODO - remove this as any, at the new PR to fix the HOC erros +export default connect(mapStateToProps)(withTheme(EmojiPicker)) as any; diff --git a/app/containers/LoginServices.tsx b/app/containers/LoginServices.tsx index bf175dd70..aab5c889e 100644 --- a/app/containers/LoginServices.tsx +++ b/app/containers/LoginServices.tsx @@ -423,4 +423,4 @@ const mapStateToProps = (state: any) => ({ services: state.login.services }); -export default connect(mapStateToProps)(withTheme(LoginServices)); +export default connect(mapStateToProps)(withTheme(LoginServices)) as any; diff --git a/app/containers/MessageBox/EmojiKeyboard.tsx b/app/containers/MessageBox/EmojiKeyboard.tsx index bbb0e20ad..91acc45d1 100644 --- a/app/containers/MessageBox/EmojiKeyboard.tsx +++ b/app/containers/MessageBox/EmojiKeyboard.tsx @@ -13,7 +13,7 @@ interface IMessageBoxEmojiKeyboard { } export default class EmojiKeyboard extends React.PureComponent { - private readonly baseUrl: any; + private readonly baseUrl: string; constructor(props: IMessageBoxEmojiKeyboard) { super(props); diff --git a/app/containers/MessageBox/index.tsx b/app/containers/MessageBox/index.tsx index 047c128bd..8645a165c 100644 --- a/app/containers/MessageBox/index.tsx +++ b/app/containers/MessageBox/index.tsx @@ -1124,4 +1124,4 @@ const dispatchToProps = { typing: (rid: any, status: any) => userTypingAction(rid, status) }; // @ts-ignore -export default connect(mapStateToProps, dispatchToProps, null, { forwardRef: true })(withActionSheet(MessageBox)); +export default connect(mapStateToProps, dispatchToProps, null, { forwardRef: true })(withActionSheet(MessageBox)) as any; diff --git a/app/containers/SearchBox.tsx b/app/containers/SearchBox.tsx index 4a08c91ce..6668e0f76 100644 --- a/app/containers/SearchBox.tsx +++ b/app/containers/SearchBox.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { StyleSheet, Text, View } from 'react-native'; +import { StyleSheet, Text, TextInputProps, View } from 'react-native'; import Touchable from 'react-native-platform-touchable'; import TextInput from '../presentation/TextInput'; @@ -45,7 +45,7 @@ const styles = StyleSheet.create({ }); interface ISearchBox { - onChangeText: () => void; + onChangeText: TextInputProps['onChangeText']; onSubmitEditing: () => void; hasCancel: boolean; onCancelPress: Function; diff --git a/app/definitions/IAttachment.ts b/app/definitions/IAttachment.ts new file mode 100644 index 000000000..168106177 --- /dev/null +++ b/app/definitions/IAttachment.ts @@ -0,0 +1,10 @@ +export interface IAttachment { + title: string; + type: string; + description: string; + title_link?: string; + image_url?: string; + image_type?: string; + video_url?: string; + video_type?: string; +} diff --git a/app/definitions/IMessage.ts b/app/definitions/IMessage.ts new file mode 100644 index 000000000..aca651c10 --- /dev/null +++ b/app/definitions/IMessage.ts @@ -0,0 +1,3 @@ +export interface IMessage { + msg: string; +} diff --git a/app/definitions/IRocketChatRecord.ts b/app/definitions/IRocketChatRecord.ts new file mode 100644 index 000000000..48d91fa84 --- /dev/null +++ b/app/definitions/IRocketChatRecord.ts @@ -0,0 +1,4 @@ +export interface IRocketChatRecord { + id: string; + updatedAt: Date; +} diff --git a/app/definitions/IRoom.ts b/app/definitions/IRoom.ts new file mode 100644 index 000000000..786c1d7c8 --- /dev/null +++ b/app/definitions/IRoom.ts @@ -0,0 +1,27 @@ +import { IRocketChatRecord } from './IRocketChatRecord'; + +export enum RoomType { + GROUP = 'p', + DIRECT = 'd', + CHANNEL = 'c', + OMNICHANNEL = 'l', + THREAD = 'thread' +} + +export interface IRoom extends IRocketChatRecord { + rid: string; + t: RoomType; + name: string; + fname: string; + prid?: string; + tmid?: string; + topic?: string; + teamMain?: boolean; + teamId?: string; + encrypted?: boolean; + visitor?: boolean; + autoTranslateLanguage?: boolean; + autoTranslate?: boolean; + observe?: Function; + usedCannedResponse: string; +} diff --git a/app/definitions/IServer.ts b/app/definitions/IServer.ts new file mode 100644 index 000000000..534a29c9c --- /dev/null +++ b/app/definitions/IServer.ts @@ -0,0 +1,16 @@ +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/definition/ITeam.js b/app/definitions/ITeam.ts similarity index 100% rename from app/definition/ITeam.js rename to app/definitions/ITeam.ts diff --git a/app/dimensions.tsx b/app/dimensions.tsx index dc164362a..676009683 100644 --- a/app/dimensions.tsx +++ b/app/dimensions.tsx @@ -22,7 +22,7 @@ export interface IDimensionsContextProps { export const DimensionsContext = React.createContext>(Dimensions.get('window')); -export function withDimensions(Component: any) { +export function withDimensions(Component: any): any { const DimensionsComponent = (props: any) => ( {contexts => } ); diff --git a/app/ee/omnichannel/views/QueueListView.js b/app/ee/omnichannel/views/QueueListView.js index defe9233f..5d537ceef 100644 --- a/app/ee/omnichannel/views/QueueListView.js +++ b/app/ee/omnichannel/views/QueueListView.js @@ -161,4 +161,5 @@ const mapStateToProps = state => ({ showAvatar: state.sortPreferences.showAvatar, displayMode: state.sortPreferences.displayMode }); + export default connect(mapStateToProps)(withDimensions(withTheme(QueueListView))); diff --git a/app/lib/rocketchat.js b/app/lib/rocketchat.js index fac6d2c1f..5bf94d085 100644 --- a/app/lib/rocketchat.js +++ b/app/lib/rocketchat.js @@ -24,7 +24,7 @@ import { selectServerFailure } from '../actions/server'; import { useSsl } from '../utils/url'; import EventEmitter from '../utils/events'; import { updatePermission } from '../actions/permissions'; -import { TEAM_TYPE } from '../definition/ITeam'; +import { TEAM_TYPE } from '../definitions/ITeam'; import { updateSettings } from '../actions/settings'; import { compareServerVersion, methods } from './utils'; import reduxStore from './createStore'; diff --git a/app/navigationTypes.ts b/app/navigationTypes.ts new file mode 100644 index 000000000..568b75d0f --- /dev/null +++ b/app/navigationTypes.ts @@ -0,0 +1,45 @@ +import { NavigatorScreenParams } from '@react-navigation/core'; + +import { IRoom } from './definitions/IRoom'; +import { IServer } from './definitions/IServer'; +import { IAttachment } from './definitions/IAttachment'; +import { MasterDetailInsideStackParamList } from './stacks/MasterDetailStack/types'; +import { OutsideParamList, InsideStackParamList } from './stacks/types'; + +export type SetUsernameStackParamList = { + SetUsernameView: { + title: string; + }; +}; + +export type StackParamList = { + AuthLoading: undefined; + OutsideStack: NavigatorScreenParams; + InsideStack: NavigatorScreenParams; + MasterDetailStack: NavigatorScreenParams; + SetUsernameStack: NavigatorScreenParams; +}; + +export type ShareInsideStackParamList = { + ShareListView: undefined; + ShareView: { + attachments: IAttachment[]; + isShareView?: boolean; + isShareExtension: boolean; + serverInfo: IServer; + text: string; + room: IRoom; + thread: any; // TODO: Change + }; + SelectServerView: undefined; +}; + +export type ShareOutsideStackParamList = { + WithoutServersView: undefined; +}; + +export type ShareAppStackParamList = { + AuthLoading?: undefined; + OutsideStack?: NavigatorScreenParams; + InsideStack?: NavigatorScreenParams; +}; diff --git a/app/share.tsx b/app/share.tsx index ceb85477d..daee2fba0 100644 --- a/app/share.tsx +++ b/app/share.tsx @@ -25,6 +25,7 @@ import { setCurrentScreen } from './utils/log'; import AuthLoadingView from './views/AuthLoadingView'; import { DimensionsContext } from './dimensions'; import debounce from './utils/debounce'; +import { ShareInsideStackParamList, ShareOutsideStackParamList, ShareAppStackParamList } from './navigationTypes'; interface IDimensions { width: number; @@ -46,7 +47,7 @@ interface IState { fontScale: number; } -const Inside = createStackNavigator(); +const Inside = createStackNavigator(); const InsideStack = () => { const { theme } = useContext(ThemeContext); @@ -65,24 +66,19 @@ const InsideStack = () => { ); }; -const Outside = createStackNavigator(); +const Outside = createStackNavigator(); const OutsideStack = () => { const { theme } = useContext(ThemeContext); return ( - + ); }; // App -const Stack = createStackNavigator(); +const Stack = createStackNavigator(); export const App = ({ root }: any) => ( <> @@ -112,7 +108,7 @@ class Root extends React.Component<{}, IState> { this.init(); } - componentWillUnmount() { + componentWillUnmount(): void { RocketChat.closeShareExtension(); unsubscribeTheme(); } diff --git a/app/stacks/InsideStack.js b/app/stacks/InsideStack.tsx similarity index 82% rename from app/stacks/InsideStack.js rename to app/stacks/InsideStack.tsx index b3de1b610..97b3b25de 100644 --- a/app/stacks/InsideStack.js +++ b/app/stacks/InsideStack.tsx @@ -1,12 +1,11 @@ import React from 'react'; import { I18nManager } from 'react-native'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createStackNavigator, StackNavigationOptions } from '@react-navigation/stack'; import { createDrawerNavigator } from '@react-navigation/drawer'; import { ThemeContext } from '../theme'; import { ModalAnimation, StackAnimation, defaultHeader, themedHeader } from '../utils/navigation'; import Sidebar from '../views/SidebarView'; - // Chats Stack import RoomView from '../views/RoomView'; import RoomsListView from '../views/RoomsListView'; @@ -37,10 +36,8 @@ import { themes } from '../constants/colors'; import ProfileView from '../views/ProfileView'; import UserPreferencesView from '../views/UserPreferencesView'; import UserNotificationPrefView from '../views/UserNotificationPreferencesView'; - // Display Preferences View import DisplayPrefsView from '../views/DisplayPrefsView'; - // Settings Stack import SettingsView from '../views/SettingsView'; import SecurityPrivacyView from '../views/SecurityPrivacyView'; @@ -49,21 +46,16 @@ import LanguageView from '../views/LanguageView'; import ThemeView from '../views/ThemeView'; import DefaultBrowserView from '../views/DefaultBrowserView'; import ScreenLockConfigView from '../views/ScreenLockConfigView'; - // Admin Stack import AdminPanelView from '../views/AdminPanelView'; - // NewMessage Stack import NewMessageView from '../views/NewMessageView'; import CreateChannelView from '../views/CreateChannelView'; - // E2ESaveYourPassword Stack import E2ESaveYourPasswordView from '../views/E2ESaveYourPasswordView'; import E2EHowItWorksView from '../views/E2EHowItWorksView'; - // E2EEnterYourPassword Stack import E2EEnterYourPasswordView from '../views/E2EEnterYourPasswordView'; - // InsideStackNavigator import AttachmentView from '../views/AttachmentView'; import ModalBlockView from '../views/ModalBlockView'; @@ -75,20 +67,33 @@ import QueueListView from '../ee/omnichannel/views/QueueListView'; import AddChannelTeamView from '../views/AddChannelTeamView'; import AddExistingChannelView from '../views/AddExistingChannelView'; import SelectListView from '../views/SelectListView'; +import { + AdminPanelStackParamList, + ChatsStackParamList, + DisplayPrefStackParamList, + DrawerParamList, + E2EEnterYourPasswordStackParamList, + E2ESaveYourPasswordStackParamList, + InsideStackParamList, + NewMessageStackParamList, + ProfileStackParamList, + SettingsStackParamList +} from './types'; // ChatsStackNavigator -const ChatsStack = createStackNavigator(); +const ChatsStack = createStackNavigator(); const ChatsStackNavigator = () => { const { theme } = React.useContext(ThemeContext); return ( - + - + { component={ThreadMessagesView} options={ThreadMessagesView.navigationOptions} /> - + - + { - - + + ); }; // ProfileStackNavigator -const ProfileStack = createStackNavigator(); +const ProfileStack = createStackNavigator(); const ProfileStackNavigator = () => { const { theme } = React.useContext(ThemeContext); return ( - + - + { }; // SettingsStackNavigator -const SettingsStack = createStackNavigator(); +const SettingsStack = createStackNavigator(); const SettingsStackNavigator = () => { const { theme } = React.useContext(ThemeContext); return ( - + - + { }; // AdminPanelStackNavigator -const AdminPanelStack = createStackNavigator(); +const AdminPanelStack = createStackNavigator(); const AdminPanelStackNavigator = () => { const { theme } = React.useContext(ThemeContext); return ( - + ); }; // DisplayPreferenceNavigator -const DisplayPrefStack = createStackNavigator(); +const DisplayPrefStack = createStackNavigator(); const DisplayPrefStackNavigator = () => { const { theme } = React.useContext(ThemeContext); return ( - + ); }; // DrawerNavigator -const Drawer = createDrawerNavigator(); +const Drawer = createDrawerNavigator(); const DrawerNavigator = () => { const { theme } = React.useContext(ThemeContext); @@ -257,12 +246,13 @@ const DrawerNavigator = () => { }; // NewMessageStackNavigator -const NewMessageStack = createStackNavigator(); +const NewMessageStack = createStackNavigator(); const NewMessageStackNavigator = () => { const { theme } = React.useContext(ThemeContext); return ( - + { }; // E2ESaveYourPasswordStackNavigator -const E2ESaveYourPasswordStack = createStackNavigator(); +const E2ESaveYourPasswordStack = createStackNavigator(); const E2ESaveYourPasswordStackNavigator = () => { const { theme } = React.useContext(ThemeContext); return ( - + { }; // E2EEnterYourPasswordStackNavigator -const E2EEnterYourPasswordStack = createStackNavigator(); +const E2EEnterYourPasswordStack = createStackNavigator(); const E2EEnterYourPasswordStackNavigator = () => { const { theme } = React.useContext(ThemeContext); return ( - + { }; // InsideStackNavigator -const InsideStack = createStackNavigator(); +const InsideStack = createStackNavigator(); const InsideStackNavigator = () => { const { theme } = React.useContext(ThemeContext); diff --git a/app/stacks/MasterDetailStack/ModalContainer.js b/app/stacks/MasterDetailStack/ModalContainer.tsx similarity index 60% rename from app/stacks/MasterDetailStack/ModalContainer.js rename to app/stacks/MasterDetailStack/ModalContainer.tsx index 7be11f8c7..aeea3d88c 100644 --- a/app/stacks/MasterDetailStack/ModalContainer.js +++ b/app/stacks/MasterDetailStack/ModalContainer.tsx @@ -1,10 +1,17 @@ import React from 'react'; import { StyleSheet, TouchableWithoutFeedback, View } from 'react-native'; -import PropTypes from 'prop-types'; +import { StackNavigationProp } from '@react-navigation/stack'; +import { NavigationContainerProps } from '@react-navigation/core'; import sharedStyles from '../../views/Styles'; import { themes } from '../../constants/colors'; +interface IModalContainer extends NavigationContainerProps { + navigation: StackNavigationProp; + children: React.ReactNode; + theme: string; +} + const styles = StyleSheet.create({ root: { flex: 1, @@ -12,11 +19,11 @@ const styles = StyleSheet.create({ justifyContent: 'center' }, backdrop: { - ...StyleSheet.absoluteFill + ...StyleSheet.absoluteFillObject } }); -export const ModalContainer = ({ navigation, children, theme }) => ( +export const ModalContainer = ({ navigation, children, theme }: IModalContainer): JSX.Element => ( navigation.pop()}> @@ -24,9 +31,3 @@ export const ModalContainer = ({ navigation, children, theme }) => ( {children} ); - -ModalContainer.propTypes = { - navigation: PropTypes.object, - children: PropTypes.element, - theme: PropTypes.string -}; diff --git a/app/stacks/MasterDetailStack/index.js b/app/stacks/MasterDetailStack/index.tsx similarity index 87% rename from app/stacks/MasterDetailStack/index.js rename to app/stacks/MasterDetailStack/index.tsx index 71828a6a2..4cc256125 100644 --- a/app/stacks/MasterDetailStack/index.js +++ b/app/stacks/MasterDetailStack/index.tsx @@ -1,12 +1,10 @@ import React, { useEffect } from 'react'; -import PropTypes from 'prop-types'; import { useIsFocused } from '@react-navigation/native'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createStackNavigator, StackNavigationOptions, StackNavigationProp } from '@react-navigation/stack'; import { createDrawerNavigator } from '@react-navigation/drawer'; import { ThemeContext } from '../../theme'; import { FadeFromCenterModal, StackAnimation, defaultHeader, themedHeader } from '../../utils/navigation'; - // Chats Stack import RoomView from '../../views/RoomView'; import RoomsListView from '../../views/RoomsListView'; @@ -46,7 +44,6 @@ import UserPreferencesView from '../../views/UserPreferencesView'; import UserNotificationPrefView from '../../views/UserNotificationPreferencesView'; import SecurityPrivacyView from '../../views/SecurityPrivacyView'; import E2EEncryptionSecurityView from '../../views/E2EEncryptionSecurityView'; - // InsideStackNavigator import AttachmentView from '../../views/AttachmentView'; import ModalBlockView from '../../views/ModalBlockView'; @@ -63,9 +60,15 @@ import AddChannelTeamView from '../../views/AddChannelTeamView'; import AddExistingChannelView from '../../views/AddExistingChannelView'; import SelectListView from '../../views/SelectListView'; import { ModalContainer } from './ModalContainer'; +import { + MasterDetailChatsStackParamList, + MasterDetailDrawerParamList, + MasterDetailInsideStackParamList, + ModalStackParamList +} from './types'; // ChatsStackNavigator -const ChatsStack = createStackNavigator(); +const ChatsStack = createStackNavigator(); const ChatsStackNavigator = React.memo(() => { const { theme } = React.useContext(ThemeContext); @@ -82,28 +85,35 @@ const ChatsStackNavigator = React.memo(() => { }, [isFocused]); return ( - + ); }); // DrawerNavigator -const Drawer = createDrawerNavigator(); +const Drawer = createDrawerNavigator(); const DrawerNavigator = React.memo(() => ( } drawerType='permanent'> )); -const ModalStack = createStackNavigator(); -const ModalStackNavigator = React.memo(({ navigation }) => { +export interface INavigation { + navigation: StackNavigationProp; +} + +const ModalStack = createStackNavigator(); +const ModalStackNavigator = React.memo(({ navigation }: INavigation) => { const { theme } = React.useContext(ThemeContext); return ( - + { /> - + { component={ForwardLivechatView} options={ForwardLivechatView.navigationOptions} /> - - + + @@ -226,21 +224,13 @@ const ModalStackNavigator = React.memo(({ navigation }) => { component={E2EEnterYourPasswordView} options={E2EEnterYourPasswordView.navigationOptions} /> - + - + { ); }); -ModalStackNavigator.propTypes = { - navigation: PropTypes.object -}; - // InsideStackNavigator -const InsideStack = createStackNavigator(); +const InsideStack = createStackNavigator(); const InsideStackNavigator = React.memo(() => { const { theme } = React.useContext(ThemeContext); return ( - + diff --git a/app/stacks/MasterDetailStack/types.ts b/app/stacks/MasterDetailStack/types.ts new file mode 100644 index 000000000..2e5246c25 --- /dev/null +++ b/app/stacks/MasterDetailStack/types.ts @@ -0,0 +1,203 @@ +import { TextInputProps } from 'react-native'; +import { NavigatorScreenParams } from '@react-navigation/core'; + +import { IAttachment } from '../../definitions/IAttachment'; +import { IMessage } from '../../definitions/IMessage'; +import { IRoom, RoomType } from '../../definitions/IRoom'; + +export type MasterDetailChatsStackParamList = { + RoomView: { + rid: string; + t: RoomType; + tmid?: string; + message?: string; + name?: string; + fname?: string; + prid?: string; + room: IRoom; + jumpToMessageId?: string; + jumpToThreadId?: string; + roomUserId?: string; + }; +}; + +export type MasterDetailDrawerParamList = { + ChatsStackNavigator: NavigatorScreenParams; +}; + +export type ModalStackParamList = { + RoomActionsView: { + room: IRoom; + member: any; + rid: string; + t: RoomType; + joined: boolean; + }; + RoomInfoView: { + room: IRoom; + member: any; + rid: string; + t: RoomType; + }; + SelectListView: { + data: any; + title: string; + infoText: string; + nextAction: Function; + showAlert: boolean; + isSearch: boolean; + onSearch: Function; + isRadio?: boolean; + }; + RoomInfoEditView: { + rid: string; + }; + RoomMembersView: { + rid: string; + room: IRoom; + }; + SearchMessagesView: { + rid: string; + t: RoomType; + encrypted?: boolean; + showCloseModal?: boolean; + }; + SelectedUsersView: { + maxUsers: number; + showButton: boolean; + title: string; + buttonText: string; + nextAction: Function; + }; + InviteUsersView: { + rid: string; + }; + AddChannelTeamView: { + teamId?: string; + teamChannels: []; // TODO: Change + }; + AddExistingChannelView: { + teamId?: boolean; + }; + InviteUsersEditView: { + rid: string; + }; + MessagesView: { + rid: string; + t: RoomType; + name: string; + }; + AutoTranslateView: { + rid: string; + room: IRoom; + }; + DirectoryView: undefined; + QueueListView: undefined; + NotificationPrefView: { + rid: string; + room: IRoom; + }; + VisitorNavigationView: { + rid: string; + }; + ForwardLivechatView: { + rid: string; + }; + CannedResponsesListView: { + rid: string; + }; + CannedResponseDetail: { + cannedResponse: { + shortcut: string; + text: string; + scopeName: string; + tags: string[]; + }; + room: IRoom; + }; + LivechatEditView: { + room: IRoom; + roomUser: any; // TODO: Change + }; + PickerView: { + title: string; + data: []; // TODO: Change + value: any; // TODO: Change + onChangeText: TextInputProps['onChangeText']; + goBack: Function; + onChangeValue: Function; + }; + ThreadMessagesView: { + rid: string; + t: RoomType; + }; + TeamChannelsView: { + teamId: string; + }; + MarkdownTableView: { + renderRows: Function; + tableWidth: number; + }; + ReadReceiptsView: { + messageId: string; + }; + SettingsView: undefined; + LanguageView: undefined; + ThemeView: undefined; + DefaultBrowserView: undefined; + ScreenLockConfigView: undefined; + StatusView: undefined; + ProfileView: undefined; + DisplayPrefsView: undefined; + AdminPanelView: undefined; + NewMessageView: undefined; + SelectedUsersViewCreateChannel: { + maxUsers: number; + showButton: boolean; + title: string; + buttonText: string; + nextAction: Function; + }; // TODO: Change + CreateChannelView: { + isTeam?: boolean; // TODO: To check + teamId?: string; + }; + CreateDiscussionView: { + channel: IRoom; + message: IMessage; + showCloseModal: boolean; + }; + E2ESaveYourPasswordView: undefined; + E2EHowItWorksView: { + showCloseModal: boolean; + }; + E2EEnterYourPasswordView: undefined; + UserPreferencesView: undefined; + UserNotificationPrefView: undefined; + SecurityPrivacyView: undefined; + E2EEncryptionSecurityView: undefined; +}; + +export type MasterDetailInsideStackParamList = { + DrawerNavigator: NavigatorScreenParams>; // TODO: Change + ModalStackNavigator: NavigatorScreenParams; + AttachmentView: { + attachment: IAttachment; + }; + ModalBlockView: { + data: any; // TODO: Change + }; + JitsiMeetView: { + rid: string; + url: string; + onlyAudio?: boolean; + }; + ShareView: { + attachments: IAttachment[]; + isShareView?: boolean; + serverInfo: {}; + text: string; + room: IRoom; + thread: any; // TODO: Change + }; +}; diff --git a/app/stacks/OutsideStack.js b/app/stacks/OutsideStack.tsx similarity index 81% rename from app/stacks/OutsideStack.js rename to app/stacks/OutsideStack.tsx index 392850c3e..fb791330f 100644 --- a/app/stacks/OutsideStack.js +++ b/app/stacks/OutsideStack.tsx @@ -1,10 +1,9 @@ import React from 'react'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createStackNavigator, StackNavigationOptions } from '@react-navigation/stack'; import { connect } from 'react-redux'; import { ThemeContext } from '../theme'; import { ModalAnimation, StackAnimation, defaultHeader, themedHeader } from '../utils/navigation'; - // Outside Stack import NewServerView from '../views/NewServerView'; import WorkspaceView from '../views/WorkspaceView'; @@ -14,37 +13,34 @@ import SendEmailConfirmationView from '../views/SendEmailConfirmationView'; import RegisterView from '../views/RegisterView'; import LegalView from '../views/LegalView'; import AuthenticationWebView from '../views/AuthenticationWebView'; +import { OutsideModalParamList, OutsideParamList } from './types'; // Outside -const Outside = createStackNavigator(); +const Outside = createStackNavigator(); const _OutsideStack = () => { const { theme } = React.useContext(ThemeContext); return ( - + - + ); }; -const mapStateToProps = state => ({ +const mapStateToProps = (state: any) => ({ root: state.app.root }); const OutsideStack = connect(mapStateToProps)(_OutsideStack); // OutsideStackModal -const OutsideModal = createStackNavigator(); +const OutsideModal = createStackNavigator(); const OutsideStackModal = () => { const { theme } = React.useContext(ThemeContext); diff --git a/app/stacks/types.ts b/app/stacks/types.ts new file mode 100644 index 000000000..c9386d939 --- /dev/null +++ b/app/stacks/types.ts @@ -0,0 +1,275 @@ +import { NavigatorScreenParams } from '@react-navigation/core'; +import { TextInputProps } from 'react-native'; +import Model from '@nozbe/watermelondb/Model'; + +import { IOptionsField } from '../views/NotificationPreferencesView/options'; +import { IServer } from '../definitions/IServer'; +import { IAttachment } from '../definitions/IAttachment'; +import { IMessage } from '../definitions/IMessage'; +import { IRoom, RoomType } from '../definitions/IRoom'; + +export type ChatsStackParamList = { + RoomsListView: undefined; + RoomView: { + rid: string; + t: RoomType; + tmid?: string; + message?: string; + name?: string; + fname?: string; + prid?: string; + room: IRoom; + jumpToMessageId?: string; + jumpToThreadId?: string; + roomUserId?: string; + }; + RoomActionsView: { + room: IRoom; + member: any; + rid: string; + t: RoomType; + joined: boolean; + }; + SelectListView: { + data: any; + title: string; + infoText: string; + nextAction: Function; + showAlert: boolean; + isSearch: boolean; + onSearch: Function; + isRadio?: boolean; + }; + RoomInfoView: { + room: IRoom; + member: any; + rid: string; + t: RoomType; + }; + RoomInfoEditView: { + rid: string; + }; + RoomMembersView: { + rid: string; + room: IRoom; + }; + SearchMessagesView: { + rid: string; + t: RoomType; + encrypted?: boolean; + showCloseModal?: boolean; + }; + SelectedUsersView: { + maxUsers?: number; + showButton?: boolean; + title?: string; + buttonText?: string; + nextAction?: Function; + }; + InviteUsersView: { + rid: string; + }; + InviteUsersEditView: { + rid: string; + }; + MessagesView: { + rid: string; + t: RoomType; + name: string; + }; + AutoTranslateView: { + rid: string; + room: IRoom; + }; + DirectoryView: undefined; + NotificationPrefView: { + rid: string; + room: Model; + }; + VisitorNavigationView: { + rid: string; + }; + ForwardLivechatView: { + rid: string; + }; + LivechatEditView: { + room: IRoom; + roomUser: any; // TODO: Change + }; + PickerView: { + title: string; + data: IOptionsField[]; + value?: any; // TODO: Change + onChangeText?: ((text: string) => IOptionsField[]) | ((term?: string) => Promise); + goBack?: boolean; + onChangeValue: Function; + }; + ThreadMessagesView: { + rid: string; + t: RoomType; + }; + TeamChannelsView: { + teamId: string; + }; + CreateChannelView: { + isTeam?: boolean; // TODO: To check + teamId?: string; + }; + AddChannelTeamView: { + teamId?: string; + teamChannels: []; // TODO: Change + }; + AddExistingChannelView: { + teamId?: string; + teamChannels: []; // TODO: Change + }; + MarkdownTableView: { + renderRows: (drawExtraBorders?: boolean) => JSX.Element; + tableWidth: number; + }; + ReadReceiptsView: { + messageId: string; + }; + QueueListView: undefined; + CannedResponsesListView: { + rid: string; + }; + CannedResponseDetail: { + cannedResponse: { + shortcut: string; + text: string; + scopeName: string; + tags: string[]; + }; + room: IRoom; + }; +}; + +export type ProfileStackParamList = { + ProfileView: undefined; + UserPreferencesView: undefined; + UserNotificationPrefView: undefined; + PickerView: { + title: string; + data: IOptionsField[]; + value: any; // TODO: Change + onChangeText?: TextInputProps['onChangeText']; + goBack?: Function; + onChangeValue: Function; + }; +}; + +export type SettingsStackParamList = { + SettingsView: undefined; + SecurityPrivacyView: undefined; + E2EEncryptionSecurityView: undefined; + LanguageView: undefined; + ThemeView: undefined; + DefaultBrowserView: undefined; + ScreenLockConfigView: undefined; + ProfileView: undefined; + DisplayPrefsView: undefined; +}; + +export type AdminPanelStackParamList = { + AdminPanelView: undefined; +}; + +export type DisplayPrefStackParamList = { + DisplayPrefsView: undefined; +}; + +export type DrawerParamList = { + ChatsStackNavigator: NavigatorScreenParams; + ProfileStackNavigator: NavigatorScreenParams; + SettingsStackNavigator: NavigatorScreenParams; + AdminPanelStackNavigator: NavigatorScreenParams; + DisplayPrefStackNavigator: NavigatorScreenParams; +}; + +export type NewMessageStackParamList = { + NewMessageView: undefined; + SelectedUsersViewCreateChannel: { + maxUsers?: number; + showButton?: boolean; + title?: string; + buttonText?: string; + nextAction?: Function; + }; // TODO: Change + CreateChannelView: { + isTeam?: boolean; // TODO: To check + teamId?: string; + }; + CreateDiscussionView: { + channel: IRoom; + message: IMessage; + showCloseModal: boolean; + }; +}; + +export type E2ESaveYourPasswordStackParamList = { + E2ESaveYourPasswordView: undefined; + E2EHowItWorksView?: { + showCloseModal?: boolean; + }; +}; + +export type E2EEnterYourPasswordStackParamList = { + E2EEnterYourPasswordView: undefined; +}; + +export type InsideStackParamList = { + DrawerNavigator: NavigatorScreenParams; + NewMessageStackNavigator: NavigatorScreenParams; + E2ESaveYourPasswordStackNavigator: NavigatorScreenParams; + E2EEnterYourPasswordStackNavigator: NavigatorScreenParams; + AttachmentView: { + attachment: IAttachment; + }; + StatusView: undefined; + ShareView: { + attachments: IAttachment[]; + isShareView?: boolean; + isShareExtension: boolean; + serverInfo: IServer; + text: string; + room: IRoom; + thread: any; // TODO: Change + }; + ModalBlockView: { + data: any; // TODO: Change; + }; + JitsiMeetView: { + rid: string; + url: string; + onlyAudio?: boolean; + }; +}; + +export type OutsideParamList = { + NewServerView: undefined; + WorkspaceView: undefined; + LoginView: { + title: string; + username?: string; + }; + ForgotPasswordView: { + title: string; + }; + SendEmailConfirmationView: { + user?: string; + }; + RegisterView: { + title: string; + }; + LegalView: undefined; +}; + +export type OutsideModalParamList = { + OutsideStack: NavigatorScreenParams; + AuthenticationWebView: { + authType: string; + url: string; + ssoToken?: string; + }; +}; diff --git a/app/theme.tsx b/app/theme.tsx index 4accff2cd..635ffda1c 100644 --- a/app/theme.tsx +++ b/app/theme.tsx @@ -12,7 +12,7 @@ interface IThemeContextProps { export const ThemeContext = React.createContext({ theme: 'light' }); -export function withTheme(Component: any) { +export function withTheme(Component: any): any { const ThemedComponent = (props: any) => ( {contexts => } ); diff --git a/app/utils/fileDownload/index.ts b/app/utils/fileDownload/index.ts index dda1a78ff..279d3b3a5 100644 --- a/app/utils/fileDownload/index.ts +++ b/app/utils/fileDownload/index.ts @@ -5,13 +5,7 @@ import EventEmitter from '../events'; import { LISTENER } from '../../containers/Toast'; import I18n from '../../i18n'; import { DOCUMENTS_PATH, DOWNLOAD_PATH } from '../../constants/localPath'; - -interface IAttachment { - title: string; - title_link: string; - type: string; - description: string; -} +import { IAttachment } from '../../definitions/IAttachment'; export const getLocalFilePathFromFile = (localPath: string, attachment: IAttachment): string => `${localPath}${attachment.title}`; diff --git a/app/views/AddChannelTeamView.tsx b/app/views/AddChannelTeamView.tsx index d477f9bad..8a72d3c96 100644 --- a/app/views/AddChannelTeamView.tsx +++ b/app/views/AddChannelTeamView.tsx @@ -2,6 +2,7 @@ import React, { useEffect } from 'react'; import { StackNavigationOptions, StackNavigationProp } from '@react-navigation/stack'; import { RouteProp } from '@react-navigation/native'; import { connect } from 'react-redux'; +import { CompositeNavigationProp } from '@react-navigation/core'; import * as List from '../containers/List'; import StatusBar from '../containers/StatusBar'; @@ -9,16 +10,24 @@ import { useTheme } from '../theme'; import * as HeaderButton from '../containers/HeaderButton'; import SafeAreaView from '../containers/SafeAreaView'; import I18n from '../i18n'; - -type TNavigation = StackNavigationProp; +import { ChatsStackParamList, DrawerParamList, NewMessageStackParamList } from '../stacks/types'; interface IAddChannelTeamView { - route: RouteProp<{ AddChannelTeamView: { teamId: string; teamChannels: object[] } }, 'AddChannelTeamView'>; - navigation: TNavigation; + navigation: CompositeNavigationProp< + StackNavigationProp, + CompositeNavigationProp, StackNavigationProp> + >; + route: RouteProp; isMasterDetail: boolean; } -const setHeader = (navigation: TNavigation, isMasterDetail: boolean) => { +const setHeader = ({ + navigation, + isMasterDetail +}: { + navigation: StackNavigationProp; + isMasterDetail: boolean; +}) => { const options: StackNavigationOptions = { headerTitle: I18n.t('Add_Channel_to_Team') }; @@ -35,7 +44,7 @@ const AddChannelTeamView = ({ navigation, route, isMasterDetail }: IAddChannelTe const { theme } = useTheme(); useEffect(() => { - setHeader(navigation, isMasterDetail); + setHeader({ navigation, isMasterDetail }); }, []); return ( diff --git a/app/views/AddExistingChannelView.tsx b/app/views/AddExistingChannelView.tsx index 5efdbf34d..86ab9b9cf 100644 --- a/app/views/AddExistingChannelView.tsx +++ b/app/views/AddExistingChannelView.tsx @@ -21,6 +21,7 @@ import { animateNextTransition } from '../utils/layoutAnimation'; import { goRoom } from '../utils/goRoom'; import { showErrorAlert } from '../utils/info'; import debounce from '../utils/debounce'; +import { ChatsStackParamList } from '../stacks/types'; interface IAddExistingChannelViewState { // TODO: refactor with Room Model @@ -31,8 +32,8 @@ interface IAddExistingChannelViewState { } interface IAddExistingChannelViewProps { - navigation: StackNavigationProp; - route: RouteProp<{ AddExistingChannelView: { teamId: string } }, 'AddExistingChannelView'>; + navigation: StackNavigationProp; + route: RouteProp; theme: string; isMasterDetail: boolean; addTeamChannelPermission: string[]; @@ -41,7 +42,7 @@ interface IAddExistingChannelViewProps { const QUERY_SIZE = 50; class AddExistingChannelView extends React.Component { - private teamId: string; + private teamId?: string; constructor(props: IAddExistingChannelViewProps) { super(props); this.query(); diff --git a/app/views/AdminPanelView/index.tsx b/app/views/AdminPanelView/index.tsx index 80f728e12..f0af5dfa0 100644 --- a/app/views/AdminPanelView/index.tsx +++ b/app/views/AdminPanelView/index.tsx @@ -9,6 +9,7 @@ import * as HeaderButton from '../../containers/HeaderButton'; import { withTheme } from '../../theme'; import { getUserSelector } from '../../selectors/login'; import SafeAreaView from '../../containers/SafeAreaView'; +import { AdminPanelStackParamList } from '../../stacks/types'; interface IAdminPanelViewProps { baseUrl: string; @@ -16,7 +17,7 @@ interface IAdminPanelViewProps { } interface INavigationOptions { - navigation: DrawerScreenProps; + navigation: DrawerScreenProps; isMasterDetail: boolean; } diff --git a/app/views/AttachmentView.tsx b/app/views/AttachmentView.tsx index 90adf8b42..09e2d5d61 100644 --- a/app/views/AttachmentView.tsx +++ b/app/views/AttachmentView.tsx @@ -24,6 +24,8 @@ import { getUserSelector } from '../selectors/login'; import { withDimensions } from '../dimensions'; import { getHeaderHeight } from '../containers/Header'; import StatusBar from '../containers/StatusBar'; +import { InsideStackParamList } from '../stacks/types'; +import { IAttachment } from '../definitions/IAttachment'; const styles = StyleSheet.create({ container: { @@ -31,24 +33,14 @@ const styles = StyleSheet.create({ } }); -// TODO: refactor when react-navigation is done -export interface IAttachment { - title: string; - title_link?: string; - image_url?: string; - image_type?: string; - video_url?: string; - video_type?: string; -} - interface IAttachmentViewState { attachment: IAttachment; loading: boolean; } interface IAttachmentViewProps { - navigation: StackNavigationProp; - route: RouteProp<{ AttachmentView: { attachment: IAttachment } }, 'AttachmentView'>; + navigation: StackNavigationProp; + route: RouteProp; theme: string; baseUrl: string; width: number; diff --git a/app/views/AuthenticationWebView.tsx b/app/views/AuthenticationWebView.tsx index 870af9560..ac304fbfb 100644 --- a/app/views/AuthenticationWebView.tsx +++ b/app/views/AuthenticationWebView.tsx @@ -4,7 +4,9 @@ import { connect } from 'react-redux'; import parse from 'url-parse'; import { StackNavigationProp } from '@react-navigation/stack'; import { WebViewMessage } from 'react-native-webview/lib/WebViewTypes'; +import { RouteProp } from '@react-navigation/core'; +import { OutsideModalParamList } from '../stacks/types'; import RocketChat from '../lib/rocketchat'; import { isIOS } from '../utils/deviceInfo'; import StatusBar from '../containers/StatusBar'; @@ -41,17 +43,9 @@ window.addEventListener('popstate', function() { }); `; -interface IRoute { - params: { - authType: string; - url: string; - ssoToken?: string; - }; -} - interface INavigationOption { - navigation: StackNavigationProp; - route: IRoute; + navigation: StackNavigationProp; + route: RouteProp; } interface IAuthenticationWebView extends INavigationOption { diff --git a/app/views/AutoTranslateView/index.tsx b/app/views/AutoTranslateView/index.tsx index 92a77543a..f840ca12a 100644 --- a/app/views/AutoTranslateView/index.tsx +++ b/app/views/AutoTranslateView/index.tsx @@ -1,6 +1,8 @@ import React from 'react'; import { FlatList, StyleSheet, Switch } from 'react-native'; +import { RouteProp } from '@react-navigation/core'; +import { ChatsStackParamList } from '../../stacks/types'; import RocketChat from '../../lib/rocketchat'; import I18n from '../../i18n'; import StatusBar from '../../containers/StatusBar'; @@ -9,6 +11,7 @@ import { SWITCH_TRACK_COLOR, themes } from '../../constants/colors'; import { withTheme } from '../../theme'; import SafeAreaView from '../../containers/SafeAreaView'; import { events, logEvent } from '../../utils/log'; +import { IRoom } from '../../definitions/IRoom'; const styles = StyleSheet.create({ list: { @@ -16,19 +19,8 @@ const styles = StyleSheet.create({ } }); -interface IRoom { - observe: Function; - autoTranslateLanguage: boolean; - autoTranslate: boolean; -} - interface IAutoTranslateViewProps { - route: { - params: { - rid?: string; - room?: IRoom; - }; - }; + route: RouteProp; theme: string; } diff --git a/app/views/CreateChannelView.tsx b/app/views/CreateChannelView.tsx index 45b2cc2f2..e8d719ab4 100644 --- a/app/views/CreateChannelView.tsx +++ b/app/views/CreateChannelView.tsx @@ -25,6 +25,7 @@ import { events, logEvent } from '../utils/log'; import SafeAreaView from '../containers/SafeAreaView'; import RocketChat from '../lib/rocketchat'; import sharedStyles from './Styles'; +import { ChatsStackParamList } from '../stacks/types'; const styles = StyleSheet.create({ container: { @@ -91,8 +92,8 @@ interface ICreateChannelViewState { } interface ICreateChannelViewProps { - navigation: StackNavigationProp; - route: RouteProp<{ CreateChannelView: { isTeam: boolean; teamId: string } }, 'CreateChannelView'>; + navigation: StackNavigationProp; + route: RouteProp; baseUrl: string; create: (data: ICreateFunction) => void; removeUser: (user: IOtherUser) => void; @@ -118,7 +119,7 @@ interface ISwitch extends SwitchProps { } class CreateChannelView extends React.Component { - private teamId: string; + private teamId?: string; constructor(props: ICreateChannelViewProps) { super(props); @@ -240,7 +241,7 @@ class CreateChannelView extends React.Component { ) : null, headerLeft: showCloseModal ? () => : undefined - }); + } as StackNavigationOptions); }; submit = () => { diff --git a/app/views/CreateDiscussionView/interfaces.ts b/app/views/CreateDiscussionView/interfaces.ts index 468833119..e9d076b16 100644 --- a/app/views/CreateDiscussionView/interfaces.ts +++ b/app/views/CreateDiscussionView/interfaces.ts @@ -1,14 +1,11 @@ +import { RouteProp } from '@react-navigation/core'; +import { StackNavigationProp } from '@react-navigation/stack'; + +import { NewMessageStackParamList } from '../../stacks/types'; + export interface ICreateChannelViewProps { - navigation: any; - route: { - params?: { - channel: string; - message: { - msg: string; - }; - showCloseModal: boolean; - }; - }; + navigation: StackNavigationProp; + route: RouteProp; server: string; user: { id: string; diff --git a/app/views/DirectoryView/index.tsx b/app/views/DirectoryView/index.tsx index 25d53b831..9197815bd 100644 --- a/app/views/DirectoryView/index.tsx +++ b/app/views/DirectoryView/index.tsx @@ -1,7 +1,9 @@ import React from 'react'; import { FlatList, Text, View } from 'react-native'; import { connect } from 'react-redux'; +import { StackNavigationProp } from '@react-navigation/stack'; +import { ChatsStackParamList } from '../../stacks/types'; import * as List from '../../containers/List'; import Touch from '../../utils/touch'; import RocketChat from '../../lib/rocketchat'; @@ -24,7 +26,7 @@ import styles from './styles'; import Options from './Options'; interface IDirectoryViewProps { - navigation: object; + navigation: StackNavigationProp; baseUrl: string; isFederationEnabled: boolean; user: { diff --git a/app/views/E2EEnterYourPasswordView.tsx b/app/views/E2EEnterYourPasswordView.tsx index dd9cdfa8a..6d63f90dd 100644 --- a/app/views/E2EEnterYourPasswordView.tsx +++ b/app/views/E2EEnterYourPasswordView.tsx @@ -17,6 +17,7 @@ import KeyboardView from '../presentation/KeyboardView'; import StatusBar from '../containers/StatusBar'; import { events, logEvent } from '../utils/log'; import sharedStyles from './Styles'; +import { E2EEnterYourPasswordStackParamList } from '../stacks/types'; const styles = StyleSheet.create({ container: { @@ -36,7 +37,7 @@ interface IE2EEnterYourPasswordViewState { interface IE2EEnterYourPasswordViewProps { encryptionDecodeKey: (password: string) => void; theme: string; - navigation: StackNavigationProp; + navigation: StackNavigationProp; } class E2EEnterYourPasswordView extends React.Component { diff --git a/app/views/E2EHowItWorksView.tsx b/app/views/E2EHowItWorksView.tsx index 0fbdf77a1..fce1a2d0c 100644 --- a/app/views/E2EHowItWorksView.tsx +++ b/app/views/E2EHowItWorksView.tsx @@ -9,6 +9,7 @@ import * as HeaderButton from '../containers/HeaderButton'; import Markdown from '../containers/markdown'; import { withTheme } from '../theme'; import I18n from '../i18n'; +import { E2ESaveYourPasswordStackParamList } from '../stacks/types'; const styles = StyleSheet.create({ container: { @@ -23,8 +24,8 @@ const styles = StyleSheet.create({ }); interface INavigation { - navigation: StackNavigationProp; - route: RouteProp<{ E2EHowItWorksView: { showCloseModal: boolean } }, 'E2EHowItWorksView'>; + navigation: StackNavigationProp; + route: RouteProp; } interface IE2EHowItWorksViewProps extends INavigation { diff --git a/app/views/E2ESaveYourPasswordView.tsx b/app/views/E2ESaveYourPasswordView.tsx index 1c4e13a5a..3d9a32ee1 100644 --- a/app/views/E2ESaveYourPasswordView.tsx +++ b/app/views/E2ESaveYourPasswordView.tsx @@ -19,6 +19,7 @@ import Button from '../containers/Button'; import { withTheme } from '../theme'; import I18n from '../i18n'; import sharedStyles from './Styles'; +import { E2ESaveYourPasswordStackParamList } from '../stacks/types'; const styles = StyleSheet.create({ container: { @@ -60,7 +61,7 @@ interface IE2ESaveYourPasswordViewState { interface IE2ESaveYourPasswordViewProps { server: string; - navigation: StackNavigationProp; + navigation: StackNavigationProp; encryptionSetBanner(): void; theme: string; } diff --git a/app/views/ForgotPasswordView.tsx b/app/views/ForgotPasswordView.tsx index c08a1acdd..375d089d4 100644 --- a/app/views/ForgotPasswordView.tsx +++ b/app/views/ForgotPasswordView.tsx @@ -14,6 +14,7 @@ import { themes } from '../constants/colors'; import FormContainer, { FormContainerInner } from '../containers/FormContainer'; import { events, logEvent } from '../utils/log'; import sharedStyles from './Styles'; +import { OutsideParamList } from '../stacks/types'; interface IForgotPasswordViewState { email: string; @@ -22,8 +23,8 @@ interface IForgotPasswordViewState { } interface IForgotPasswordViewProps { - navigation: StackNavigationProp; - route: RouteProp<{ ForgotPasswordView: { title: string } }, 'ForgotPasswordView'>; + navigation: StackNavigationProp; + route: RouteProp; theme: string; } diff --git a/app/views/ForwardLivechatView.tsx b/app/views/ForwardLivechatView.tsx index 42a29782d..ea17466dd 100644 --- a/app/views/ForwardLivechatView.tsx +++ b/app/views/ForwardLivechatView.tsx @@ -14,6 +14,7 @@ import OrSeparator from '../containers/OrSeparator'; import Input from '../containers/UIKit/MultiSelect/Input'; import { forwardRoom as forwardRoomAction } from '../actions/room'; import { ILivechatDepartment } from './definition/ILivechatDepartment'; +import { ChatsStackParamList } from '../stacks/types'; const styles = StyleSheet.create({ container: { @@ -47,8 +48,8 @@ interface IParsedData { } interface IForwardLivechatViewProps { - navigation: StackNavigationProp; - route: RouteProp<{ ForwardLivechatView: { rid: string } }, 'ForwardLivechatView'>; + navigation: StackNavigationProp; + route: RouteProp; theme: string; forwardRoom: (rid: string, transferData: ITransferData) => void; } diff --git a/app/views/InviteUsersEditView/index.tsx b/app/views/InviteUsersEditView/index.tsx index 62ce51212..4ae1a67df 100644 --- a/app/views/InviteUsersEditView/index.tsx +++ b/app/views/InviteUsersEditView/index.tsx @@ -19,6 +19,7 @@ import { withTheme } from '../../theme'; import SafeAreaView from '../../containers/SafeAreaView'; import { events, logEvent } from '../../utils/log'; import styles from './styles'; +import { ChatsStackParamList } from '../../stacks/types'; const OPTIONS = { days: [ @@ -67,9 +68,9 @@ const OPTIONS = { ] }; -interface IInviteUsersEditView { - navigation: StackNavigationProp; - route: RouteProp<{ InviteUsersEditView: { rid: string } }, 'InviteUsersEditView'>; +interface IInviteUsersEditViewProps { + navigation: StackNavigationProp; + route: RouteProp; theme: string; createInviteLink(rid: string): void; inviteLinksSetParams(params: { [key: string]: number }): void; @@ -77,14 +78,14 @@ interface IInviteUsersEditView { maxUses: number; } -class InviteUsersView extends React.Component { +class InviteUsersEditView extends React.Component { static navigationOptions = (): StackNavigationOptions => ({ title: I18n.t('Invite_users') }); private rid: string; - constructor(props: IInviteUsersEditView) { + constructor(props: IInviteUsersEditViewProps) { super(props); this.rid = props.route.params?.rid; } @@ -160,4 +161,4 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({ createInviteLink: (rid: string) => dispatch(inviteLinksCreateAction(rid)) }); -export default connect(mapStateToProps, mapDispatchToProps)(withTheme(InviteUsersView)); +export default connect(mapStateToProps, mapDispatchToProps)(withTheme(InviteUsersEditView)); diff --git a/app/views/InviteUsersView/index.tsx b/app/views/InviteUsersView/index.tsx index cfcd3fa11..b7bf30710 100644 --- a/app/views/InviteUsersView/index.tsx +++ b/app/views/InviteUsersView/index.tsx @@ -6,6 +6,7 @@ import { StackNavigationProp, StackNavigationOptions } from '@react-navigation/s import { RouteProp } from '@react-navigation/core'; import { Dispatch } from 'redux'; +import { ChatsStackParamList } from '../../stacks/types'; import { inviteLinksClear as inviteLinksClearAction, inviteLinksCreate as inviteLinksCreateAction @@ -22,9 +23,9 @@ import SafeAreaView from '../../containers/SafeAreaView'; import { events, logEvent } from '../../utils/log'; import styles from './styles'; -interface IInviteUsersView { - navigation: StackNavigationProp; - route: RouteProp; +interface IInviteUsersViewProps { + navigation: StackNavigationProp; + route: RouteProp; theme: string; timeDateFormat: string; invite: { @@ -36,14 +37,14 @@ interface IInviteUsersView { createInviteLink(rid: string): void; clearInviteLink(): void; } -class InviteUsersView extends React.Component { +class InviteUsersView extends React.Component { private rid: string; static navigationOptions: StackNavigationOptions = { title: I18n.t('Invite_users') }; - constructor(props: IInviteUsersView) { + constructor(props: IInviteUsersViewProps) { super(props); this.rid = props.route.params?.rid; } diff --git a/app/views/JitsiMeetView.tsx b/app/views/JitsiMeetView.tsx index 44034cda2..aa6658d20 100644 --- a/app/views/JitsiMeetView.tsx +++ b/app/views/JitsiMeetView.tsx @@ -12,6 +12,7 @@ import ActivityIndicator from '../containers/ActivityIndicator'; import { events, logEvent } from '../utils/log'; import { isAndroid, isIOS } from '../utils/deviceInfo'; import { withTheme } from '../theme'; +import { InsideStackParamList } from '../stacks/types'; const formatUrl = (url: string, baseUrl: string, uriSize: number, avatarAuthURLFragment: string) => `${baseUrl}/avatar/${url}?format=png&width=${uriSize}&height=${uriSize}${avatarAuthURLFragment}`; @@ -25,8 +26,8 @@ interface IJitsiMeetViewState { } interface IJitsiMeetViewProps { - navigation: StackNavigationProp; - route: RouteProp<{ JitsiMeetView: { rid: string; url: string; onlyAudio?: boolean } }, 'JitsiMeetView'>; + navigation: StackNavigationProp; + route: RouteProp; baseUrl: string; theme: string; user: { diff --git a/app/views/LoginView.tsx b/app/views/LoginView.tsx index 4643687e2..e43505f3f 100644 --- a/app/views/LoginView.tsx +++ b/app/views/LoginView.tsx @@ -15,6 +15,7 @@ import TextInput from '../containers/TextInput'; import { loginRequest as loginRequestAction } from '../actions/login'; import LoginServices from '../containers/LoginServices'; import sharedStyles from './Styles'; +import { OutsideParamList } from '../stacks/types'; const styles = StyleSheet.create({ registerDisabled: { @@ -47,9 +48,9 @@ const styles = StyleSheet.create({ } }); -interface IProps { - navigation: StackNavigationProp; - route: RouteProp; +interface ILoginViewProps { + navigation: StackNavigationProp; + route: RouteProp; Site_Name: string; Accounts_RegistrationForm: string; Accounts_RegistrationForm_LinkReplacementText: string; @@ -67,15 +68,15 @@ interface IProps { inviteLinkToken: string; } -class LoginView extends React.Component { +class LoginView extends React.Component { private passwordInput: any; - static navigationOptions = ({ route, navigation }: Partial) => ({ + static navigationOptions = ({ route, navigation }: ILoginViewProps) => ({ title: route?.params?.title ?? 'Rocket.Chat', headerRight: () => }); - constructor(props: IProps) { + constructor(props: ILoginViewProps) { super(props); this.state = { user: props.route.params?.username ?? '', @@ -83,7 +84,7 @@ class LoginView extends React.Component { }; } - UNSAFE_componentWillReceiveProps(nextProps: IProps) { + UNSAFE_componentWillReceiveProps(nextProps: ILoginViewProps) { const { error } = this.props; if (nextProps.failure && !dequal(error, nextProps.error)) { if (nextProps.error?.error === 'error-invalid-email') { diff --git a/app/views/MarkdownTableView.tsx b/app/views/MarkdownTableView.tsx index a65994eef..e260199e0 100644 --- a/app/views/MarkdownTableView.tsx +++ b/app/views/MarkdownTableView.tsx @@ -7,12 +7,10 @@ import I18n from '../i18n'; import { isIOS } from '../utils/deviceInfo'; import { themes } from '../constants/colors'; import { withTheme } from '../theme'; +import { ChatsStackParamList } from '../stacks/types'; interface IMarkdownTableViewProps { - route: RouteProp< - { MarkdownTableView: { renderRows: (drawExtraBorders?: boolean) => JSX.Element; tableWidth: number } }, - 'MarkdownTableView' - >; + route: RouteProp; theme: string; } diff --git a/app/views/MessagesView/index.tsx b/app/views/MessagesView/index.tsx index a948edcd1..14532051b 100644 --- a/app/views/MessagesView/index.tsx +++ b/app/views/MessagesView/index.tsx @@ -3,8 +3,9 @@ import { FlatList, Text, View } from 'react-native'; import { connect } from 'react-redux'; import { dequal } from 'dequal'; import { StackNavigationProp } from '@react-navigation/stack'; -import { RouteProp } from '@react-navigation/core'; +import { CompositeNavigationProp, RouteProp } from '@react-navigation/core'; +import { MasterDetailInsideStackParamList } from '../../stacks/MasterDetailStack/types'; import Message from '../../containers/message'; import ActivityIndicator from '../../containers/ActivityIndicator'; import I18n from '../../i18n'; @@ -18,22 +19,19 @@ import { withActionSheet } from '../../containers/ActionSheet'; import SafeAreaView from '../../containers/SafeAreaView'; import getThreadName from '../../lib/methods/getThreadName'; import styles from './styles'; - -type TMessagesViewRouteParams = { - MessagesView: { - rid: string; - t: string; - name: string; - }; -}; +import { ChatsStackParamList } from '../../stacks/types'; +import { IRoom, RoomType } from '../../definitions/IRoom'; interface IMessagesViewProps { user: { id: string; }; baseUrl: string; - navigation: StackNavigationProp; - route: RouteProp; + navigation: CompositeNavigationProp< + StackNavigationProp, + StackNavigationProp + >; + route: RouteProp; customEmojis: { [key: string]: string }; theme: string; showActionSheet: Function; @@ -41,6 +39,14 @@ interface IMessagesViewProps { isMasterDetail: boolean; } +interface IRoomInfoParam { + room: IRoom; + member: any; + rid: string; + t: RoomType; + joined: boolean; +} + interface IMessagesViewState { loading: boolean; messages: []; @@ -65,17 +71,22 @@ interface IMessageItem { } interface IParams { - rid?: string; - jumpToMessageId: string; - t?: string; - room: any; + rid: string; + t: RoomType; tmid?: string; + message?: string; name?: string; + fname?: string; + prid?: string; + room: IRoom; + jumpToMessageId?: string; + jumpToThreadId?: string; + roomUserId?: string; } class MessagesView extends React.Component { - private rid?: string; - private t?: string; + private rid: string; + private t: RoomType; private content: any; private room: any; @@ -121,7 +132,7 @@ class MessagesView extends React.Component { }); }; - navToRoomInfo = (navParam: { rid: string }) => { + navToRoomInfo = (navParam: IRoomInfoParam) => { const { navigation, user } = this.props; if (navParam.rid === user.id) { return; @@ -147,7 +158,7 @@ class MessagesView extends React.Component { ...params, tmid: item.tmid, name: await getThreadName(this.rid, item.tmid, item._id), - t: 'thread' + t: RoomType.THREAD }; navigation.push('RoomView', params); } else { diff --git a/app/views/NewServerView/index.tsx b/app/views/NewServerView/index.tsx index f1458c93a..aaacdf90f 100644 --- a/app/views/NewServerView/index.tsx +++ b/app/views/NewServerView/index.tsx @@ -33,6 +33,7 @@ import { isTablet } from '../../utils/deviceInfo'; import { verticalScale, moderateScale } from '../../utils/scaling'; import { withDimensions } from '../../dimensions'; import ServerInput from './ServerInput'; +import { OutsideParamList } from '../../stacks/types'; const styles = StyleSheet.create({ onboardingImage: { @@ -73,7 +74,7 @@ export interface IServer extends Model { } interface INewServerView { - navigation: StackNavigationProp; + navigation: StackNavigationProp; theme: string; connecting: boolean; connectServer(server: string, username?: string, fromServerHistory?: boolean): void; diff --git a/app/views/NotificationPreferencesView/index.tsx b/app/views/NotificationPreferencesView/index.tsx index a020c1631..5e33cec49 100644 --- a/app/views/NotificationPreferencesView/index.tsx +++ b/app/views/NotificationPreferencesView/index.tsx @@ -17,6 +17,7 @@ import SafeAreaView from '../../containers/SafeAreaView'; import log, { events, logEvent } from '../../utils/log'; import sharedStyles from '../Styles'; import { OPTIONS } from './options'; +import { ChatsStackParamList } from '../../stacks/types'; const styles = StyleSheet.create({ pickerText: { @@ -26,16 +27,8 @@ const styles = StyleSheet.create({ }); interface INotificationPreferencesView { - navigation: StackNavigationProp; - route: RouteProp< - { - NotificationPreferencesView: { - rid: string; - room: Model; - }; - }, - 'NotificationPreferencesView' - >; + navigation: StackNavigationProp; + route: RouteProp; theme: string; } diff --git a/app/views/NotificationPreferencesView/options.ts b/app/views/NotificationPreferencesView/options.ts index 4035c0380..a2b3251c6 100644 --- a/app/views/NotificationPreferencesView/options.ts +++ b/app/views/NotificationPreferencesView/options.ts @@ -1,4 +1,4 @@ -interface IOptionsField { +export interface IOptionsField { label: string; value: string | number; second?: number; diff --git a/app/views/PickerView.tsx b/app/views/PickerView.tsx index 002979b20..db2a7a265 100644 --- a/app/views/PickerView.tsx +++ b/app/views/PickerView.tsx @@ -11,6 +11,8 @@ import * as List from '../containers/List'; import SearchBox from '../containers/SearchBox'; import SafeAreaView from '../containers/SafeAreaView'; import sharedStyles from './Styles'; +import { ChatsStackParamList } from '../stacks/types'; +import { IOptionsField } from './NotificationPreferencesView/options'; const styles = StyleSheet.create({ search: { @@ -25,37 +27,21 @@ const styles = StyleSheet.create({ } }); -interface IData { - label: string; - value: string; - second?: string; -} - interface IItem { - item: IData; + item: IOptionsField; selected: boolean; onItemPress: () => void; theme: string; } interface IPickerViewState { - data: IData[]; + data: IOptionsField[]; value: string; } -interface IParams { - title: string; - value: string; - data: IData[]; - onChangeText: (value: string) => IData[]; - goBack: boolean; - onChange: Function; - onChangeValue: (value: string) => void; -} - interface IPickerViewProps { - navigation: StackNavigationProp; - route: RouteProp<{ PickerView: IParams }, 'PickerView'>; + navigation: StackNavigationProp; + route: RouteProp; theme: string; } @@ -69,7 +55,7 @@ const Item = React.memo(({ item, selected, onItemPress, theme }: IItem) => ( )); class PickerView extends React.PureComponent { - private onSearch: (text: string) => IData[]; + private onSearch?: ((text: string) => IOptionsField[]) | ((term?: string | undefined) => Promise); static navigationOptions = ({ route }: IPickerViewProps) => ({ title: route.params?.title ?? I18n.t('Select_an_option') @@ -126,13 +112,13 @@ class PickerView extends React.PureComponent {this.renderSearch()} item.value} + keyExtractor={item => item.value as string} renderItem={({ item }) => ( this.onChangeValue(item.value)} + onItemPress={() => this.onChangeValue(item.value as string)} /> )} ItemSeparatorComponent={List.Separator} diff --git a/app/views/ProfileView/interfaces.ts b/app/views/ProfileView/interfaces.ts index 00117203e..bfec50c0d 100644 --- a/app/views/ProfileView/interfaces.ts +++ b/app/views/ProfileView/interfaces.ts @@ -1,6 +1,8 @@ import { StackNavigationProp } from '@react-navigation/stack'; import React from 'react'; +import { ProfileStackParamList } from '../../stacks/types'; + export interface IUser { id: string; name: string; @@ -31,14 +33,12 @@ export interface IAvatarButton { } export interface INavigationOptions { - navigation: StackNavigationProp; + navigation: StackNavigationProp; isMasterDetail?: boolean; } export interface IProfileViewProps { user: IUser; - navigation: StackNavigationProp; - isMasterDetail?: boolean; baseUrl: string; Accounts_AllowEmailChange: boolean; Accounts_AllowPasswordChange: boolean; diff --git a/app/views/ReadReceiptView/index.tsx b/app/views/ReadReceiptView/index.tsx index 9f1a00675..a40327b21 100644 --- a/app/views/ReadReceiptView/index.tsx +++ b/app/views/ReadReceiptView/index.tsx @@ -16,6 +16,7 @@ import { withTheme } from '../../theme'; import { themes } from '../../constants/colors'; import SafeAreaView from '../../containers/SafeAreaView'; import styles from './styles'; +import { ChatsStackParamList } from '../../stacks/types'; interface IReceipts { _id: string; @@ -36,8 +37,8 @@ interface IReadReceiptViewState { } interface INavigationOption { - navigation: StackNavigationProp; - route: RouteProp<{ ReadReceiptView: { messageId: string } }, 'ReadReceiptView'>; + navigation: StackNavigationProp; + route: RouteProp; isMasterDetail: boolean; } diff --git a/app/views/RegisterView.tsx b/app/views/RegisterView.tsx index 045712163..ae5f46bd9 100644 --- a/app/views/RegisterView.tsx +++ b/app/views/RegisterView.tsx @@ -5,6 +5,7 @@ import { RouteProp } from '@react-navigation/core'; import { connect } from 'react-redux'; import RNPickerSelect from 'react-native-picker-select'; +import { OutsideParamList } from '../stacks/types'; import log, { events, logEvent } from '../utils/log'; import Button from '../containers/Button'; import I18n from '../i18n'; @@ -51,8 +52,8 @@ const styles = StyleSheet.create({ }); interface IProps { - navigation: StackNavigationProp; - route: RouteProp; + navigation: StackNavigationProp; + route: RouteProp; server: string; Site_Name: string; Gitlab_URL: string; diff --git a/app/views/SearchMessagesView/index.tsx b/app/views/SearchMessagesView/index.tsx index a9be99918..a85df6745 100644 --- a/app/views/SearchMessagesView/index.tsx +++ b/app/views/SearchMessagesView/index.tsx @@ -1,11 +1,13 @@ import React from 'react'; import { StackNavigationOptions, StackNavigationProp } from '@react-navigation/stack'; -import { RouteProp } from '@react-navigation/core'; +import { CompositeNavigationProp, RouteProp } from '@react-navigation/core'; import { FlatList, Text, View } from 'react-native'; import { Q } from '@nozbe/watermelondb'; import { connect } from 'react-redux'; import { dequal } from 'dequal'; +import { IRoom, RoomType } from '../../definitions/IRoom'; +import { IAttachment } from '../../definitions/IAttachment'; import RCTextInput from '../../containers/TextInput'; import ActivityIndicator from '../../containers/ActivityIndicator'; import Markdown from '../../containers/markdown'; @@ -13,7 +15,7 @@ import debounce from '../../utils/debounce'; import RocketChat from '../../lib/rocketchat'; import Message from '../../containers/message'; import scrollPersistTaps from '../../utils/scrollPersistTaps'; -import { IMessage, IMessageAttachments } from '../../containers/message/interfaces'; +import { IMessage } from '../../containers/message/interfaces'; import I18n from '../../i18n'; import StatusBar from '../../containers/StatusBar'; import log from '../../utils/log'; @@ -29,26 +31,30 @@ import getRoomInfo from '../../lib/methods/getRoomInfo'; import { isIOS } from '../../utils/deviceInfo'; import { compareServerVersion, methods } from '../../lib/utils'; import styles from './styles'; +import { InsideStackParamList, ChatsStackParamList } from '../../stacks/types'; const QUERY_SIZE = 50; -type TRouteParams = { - SearchMessagesView: { - showCloseModal?: boolean; - rid: string; - t?: string; - encrypted?: boolean; - }; -}; - interface ISearchMessagesViewState { loading: boolean; messages: IMessage[]; searchText: string; } + +interface IRoomInfoParam { + room: IRoom; + member: any; + rid: string; + t: RoomType; + joined: boolean; +} + interface INavigationOption { - navigation: StackNavigationProp; - route: RouteProp; + navigation: CompositeNavigationProp< + StackNavigationProp, + StackNavigationProp + >; + route: RouteProp; } interface ISearchMessagesViewProps extends INavigationOption { @@ -183,12 +189,12 @@ class SearchMessagesView extends React.Component { + showAttachment = (attachment: IAttachment) => { const { navigation } = this.props; navigation.navigate('AttachmentView', { attachment }); }; - navToRoomInfo = (navParam: IMessage) => { + navToRoomInfo = (navParam: IRoomInfoParam) => { const { navigation, user } = this.props; if (navParam.rid === user.id) { return; diff --git a/app/views/SendEmailConfirmationView.tsx b/app/views/SendEmailConfirmationView.tsx index 892673acc..a3aad4979 100644 --- a/app/views/SendEmailConfirmationView.tsx +++ b/app/views/SendEmailConfirmationView.tsx @@ -1,6 +1,8 @@ import React, { useEffect, useState } from 'react'; import { StackNavigationProp } from '@react-navigation/stack'; +import { RouteProp } from '@react-navigation/core'; +import { OutsideParamList } from '../stacks/types'; import TextInput from '../containers/TextInput'; import Button from '../containers/Button'; import { showErrorAlert } from '../utils/info'; @@ -12,16 +14,12 @@ import FormContainer, { FormContainerInner } from '../containers/FormContainer'; import log, { events, logEvent } from '../utils/log'; import sharedStyles from './Styles'; -interface ISendEmailConfirmationView { - navigation: StackNavigationProp; - route: { - params: { - user?: string; - }; - }; +interface ISendEmailConfirmationViewProps { + navigation: StackNavigationProp; + route: RouteProp; } -const SendEmailConfirmationView = ({ navigation, route }: ISendEmailConfirmationView): JSX.Element => { +const SendEmailConfirmationView = ({ navigation, route }: ISendEmailConfirmationViewProps): JSX.Element => { const [email, setEmail] = useState(''); const [invalidEmail, setInvalidEmail] = useState(true); const [isFetching, setIsFetching] = useState(false); diff --git a/app/views/SettingsView/index.tsx b/app/views/SettingsView/index.tsx index 02c17169b..edad2822e 100644 --- a/app/views/SettingsView/index.tsx +++ b/app/views/SettingsView/index.tsx @@ -5,6 +5,7 @@ import FastImage from '@rocket.chat/react-native-fast-image'; import CookieManager from '@react-native-cookies/cookies'; import { StackNavigationProp } from '@react-navigation/stack'; +import { SettingsStackParamList } from '../../stacks/types'; import { logout as logoutAction } from '../../actions/login'; import { selectServerRequest as selectServerRequestAction } from '../../actions/server'; import { themes } from '../../constants/colors'; @@ -29,8 +30,8 @@ import database from '../../lib/database'; import { isFDroidBuild } from '../../constants/environment'; import { getUserSelector } from '../../selectors/login'; -interface IProps { - navigation: StackNavigationProp; +interface ISettingsViewProps { + navigation: StackNavigationProp; server: { version: string; server: string; @@ -46,8 +47,8 @@ interface IProps { appStart: Function; } -class SettingsView extends React.Component { - static navigationOptions = ({ navigation, isMasterDetail }: Partial) => ({ +class SettingsView extends React.Component { + static navigationOptions = ({ navigation, isMasterDetail }: ISettingsViewProps) => ({ headerLeft: () => isMasterDetail ? ( @@ -117,7 +118,7 @@ class SettingsView extends React.Component { }); }; - navigateToScreen = (screen: string) => { + navigateToScreen = (screen: keyof SettingsStackParamList) => { /* @ts-ignore */ logEvent(events[`SE_GO_${screen.replace('View', '').toUpperCase()}`]); const { navigation } = this.props; diff --git a/app/views/ShareView/index.tsx b/app/views/ShareView/index.tsx index e10b21483..4061626e6 100644 --- a/app/views/ShareView/index.tsx +++ b/app/views/ShareView/index.tsx @@ -5,6 +5,7 @@ import { NativeModules, Text, View } from 'react-native'; import { connect } from 'react-redux'; import ShareExtension from 'rn-extensions-share'; +import { InsideStackParamList } from '../../stacks/types'; import { themes } from '../../constants/colors'; import I18n from '../../i18n'; import Loading from '../../containers/Loading'; @@ -25,7 +26,8 @@ import Thumbs from './Thumbs'; import Preview from './Preview'; import Header from './Header'; import styles from './styles'; -import { IAttachment, IServer } from './interfaces'; +import { IAttachment } from './interfaces'; +import { IRoom } from '../../definitions/IRoom'; interface IShareViewState { selected: IAttachment; @@ -33,30 +35,15 @@ interface IShareViewState { readOnly: boolean; attachments: IAttachment[]; text: string; - // TODO: Refactor when migrate room - room: any; - thread: any; + room: IRoom; + thread: any; // change maxFileSize: number; mediaAllowList: number; } interface IShareViewProps { - // TODO: Refactor after react-navigation - navigation: StackNavigationProp; - route: RouteProp< - { - ShareView: { - attachments: IAttachment[]; - isShareView?: boolean; - isShareExtension: boolean; - serverInfo: IServer; - text: string; - room: any; - thread: any; // change - }; - }, - 'ShareView' - >; + navigation: StackNavigationProp; + route: RouteProp; theme: string; user: { id: string; diff --git a/app/views/ShareView/interfaces.ts b/app/views/ShareView/interfaces.ts index 09cb4d9eb..a2231450d 100644 --- a/app/views/ShareView/interfaces.ts +++ b/app/views/ShareView/interfaces.ts @@ -13,21 +13,3 @@ 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/SidebarView/index.tsx b/app/views/SidebarView/index.tsx index f97e3ea99..c410f63df 100644 --- a/app/views/SidebarView/index.tsx +++ b/app/views/SidebarView/index.tsx @@ -18,6 +18,7 @@ import SafeAreaView from '../../containers/SafeAreaView'; import Navigation from '../../lib/Navigation'; import SidebarItem from './SidebarItem'; import styles from './styles'; +import { DrawerParamList } from '../../stacks/types'; interface ISeparatorProps { theme: string; @@ -34,8 +35,8 @@ interface ISidebarState { interface ISidebarProps { baseUrl: string; - navigation: DrawerNavigationProp; - state: DrawerNavigationState; + navigation: DrawerNavigationProp; + state: DrawerNavigationState; Site_Name: string; user: { statusText: string; @@ -305,4 +306,4 @@ const mapStateToProps = (state: any) => ({ viewPrivilegedSettingPermission: state.permissions['view-privileged-setting'] }); -export default connect(mapStateToProps)(withTheme(Sidebar)); +export default connect(mapStateToProps)(withTheme(Sidebar)) as any; diff --git a/app/views/UserNotificationPreferencesView/index.tsx b/app/views/UserNotificationPreferencesView/index.tsx index 541d5da81..8961cb38f 100644 --- a/app/views/UserNotificationPreferencesView/index.tsx +++ b/app/views/UserNotificationPreferencesView/index.tsx @@ -14,6 +14,7 @@ import ActivityIndicator from '../../containers/ActivityIndicator'; import { getUserSelector } from '../../selectors/login'; import sharedStyles from '../Styles'; import { OPTIONS } from './options'; +import { ProfileStackParamList } from '../../stacks/types'; const styles = StyleSheet.create({ pickerText: { @@ -34,7 +35,7 @@ interface IUserNotificationPreferencesViewState { } interface IUserNotificationPreferencesViewProps { - navigation: StackNavigationProp; + navigation: StackNavigationProp; theme: string; user: { id: string; diff --git a/app/views/UserPreferencesView/index.tsx b/app/views/UserPreferencesView/index.tsx index 2abce444e..59f0f9f3a 100644 --- a/app/views/UserPreferencesView/index.tsx +++ b/app/views/UserPreferencesView/index.tsx @@ -11,9 +11,10 @@ import * as List from '../../containers/List'; import { SWITCH_TRACK_COLOR } from '../../constants/colors'; import { getUserSelector } from '../../selectors/login'; import RocketChat from '../../lib/rocketchat'; +import { ProfileStackParamList } from '../../stacks/types'; interface IUserPreferencesViewProps { - navigation: StackNavigationProp; + navigation: StackNavigationProp; } const UserPreferencesView = ({ navigation }: IUserPreferencesViewProps): JSX.Element => { @@ -26,7 +27,7 @@ const UserPreferencesView = ({ navigation }: IUserPreferencesViewProps): JSX.Ele }); }, []); - const navigateToScreen = (screen: string) => { + const navigateToScreen = (screen: keyof ProfileStackParamList) => { logEvent(events.UP_GO_USER_NOTIFICATION_PREF); navigation.navigate(screen); }; diff --git a/app/views/WithoutServersView.tsx b/app/views/WithoutServersView.tsx index b77719839..43ceacc2d 100644 --- a/app/views/WithoutServersView.tsx +++ b/app/views/WithoutServersView.tsx @@ -26,7 +26,11 @@ const styles = StyleSheet.create({ } }); -class WithoutServerView extends React.Component { +interface IWithoutServerViewProps { + theme: string; +} + +class WithoutServerView extends React.Component { static navigationOptions = () => ({ title: 'Rocket.Chat', headerLeft: () => diff --git a/app/views/WorkspaceView/index.tsx b/app/views/WorkspaceView/index.tsx index 68ac5157b..827d6a44e 100644 --- a/app/views/WorkspaceView/index.tsx +++ b/app/views/WorkspaceView/index.tsx @@ -2,7 +2,9 @@ import React from 'react'; import { Text, View } from 'react-native'; import { StackNavigationProp, StackNavigationOptions } from '@react-navigation/stack'; import { connect } from 'react-redux'; +import { CompositeNavigationProp } from '@react-navigation/core'; +import { OutsideModalParamList, OutsideParamList } from '../../stacks/types'; import I18n from '../../i18n'; import Button from '../../containers/Button'; import { themes } from '../../constants/colors'; @@ -13,8 +15,10 @@ import ServerAvatar from './ServerAvatar'; import styles from './styles'; interface IWorkSpaceProp { - // TODO: waiting for the RootStackParamList https://reactnavigation.org/docs/typescript/#type-checking-screens - navigation: StackNavigationProp; + navigation: CompositeNavigationProp< + StackNavigationProp, + StackNavigationProp + >; theme: string; Site_Name: string; Site_Url: string;