From d84f3579acefbf2a4eb80ade08100888766fb3d7 Mon Sep 17 00:00:00 2001 From: Gerzon Z Date: Wed, 1 Dec 2021 19:04:31 -0400 Subject: [PATCH 01/14] Fix TypeScript compiler errors --- .../HeaderButton/HeaderButtonItem.tsx | 12 +++---- app/containers/List/ListContainer.tsx | 3 +- app/containers/List/ListHeader.tsx | 6 ++-- app/containers/List/ListInfo.tsx | 6 ++-- app/containers/List/ListSection.tsx | 6 ++-- app/containers/List/ListSeparator.tsx | 8 ++--- app/containers/SafeAreaView.tsx | 12 +++---- app/containers/StatusBar.tsx | 8 ++--- app/theme.tsx | 8 ++++- app/views/ScreenLockedView.js | 11 +++--- app/views/ShareView/Header.tsx | 8 ++--- app/views/ShareView/index.tsx | 8 ++--- app/views/SidebarView/SidebarItem.tsx | 4 +-- app/views/SidebarView/index.tsx | 36 +++++++++++-------- 14 files changed, 70 insertions(+), 66 deletions(-) diff --git a/app/containers/HeaderButton/HeaderButtonItem.tsx b/app/containers/HeaderButton/HeaderButtonItem.tsx index b350232d0b7..a7c2fd009c3 100644 --- a/app/containers/HeaderButton/HeaderButtonItem.tsx +++ b/app/containers/HeaderButton/HeaderButtonItem.tsx @@ -9,11 +9,11 @@ import sharedStyles from '../../views/Styles'; interface IHeaderButtonItem { title: string; - iconName: string; + iconName?: string; onPress(): void; - testID: string; - theme: string; - badge(): void; + testID?: string; + theme?: string; + badge?(): void; } export const BUTTON_HIT_SLOP = { @@ -44,9 +44,9 @@ const Item = ({ title, iconName, onPress, testID, theme, badge }: IHeaderButtonI <> {iconName ? ( - + ) : ( - {title} + {title} )} {badge ? badge() : null} diff --git a/app/containers/List/ListContainer.tsx b/app/containers/List/ListContainer.tsx index 408310d9f62..5ab5a0fa091 100644 --- a/app/containers/List/ListContainer.tsx +++ b/app/containers/List/ListContainer.tsx @@ -11,10 +11,9 @@ const styles = StyleSheet.create({ }); interface IListContainer { - children: JSX.Element; + children: React.ReactNode; } const ListContainer = React.memo(({ children, ...props }: IListContainer) => ( - // @ts-ignore ( - + {translateTitle ? I18n.t(title) : title} diff --git a/app/containers/List/ListInfo.tsx b/app/containers/List/ListInfo.tsx index bc4f02e3345..2bfe68e324d 100644 --- a/app/containers/List/ListInfo.tsx +++ b/app/containers/List/ListInfo.tsx @@ -20,13 +20,13 @@ const styles = StyleSheet.create({ interface IListHeader { info: string; - theme: string; - translateInfo: boolean; + theme?: string; + translateInfo?: boolean; } const ListInfo = React.memo(({ info, theme, translateInfo = true }: IListHeader) => ( - {translateInfo ? I18n.t(info) : info} + {translateInfo ? I18n.t(info) : info} )); diff --git a/app/containers/List/ListSection.tsx b/app/containers/List/ListSection.tsx index 7607ad12d72..e334f5f3f3f 100644 --- a/app/containers/List/ListSection.tsx +++ b/app/containers/List/ListSection.tsx @@ -11,9 +11,9 @@ const styles = StyleSheet.create({ }); interface IListSection { - children: JSX.Element; - title: string; - translateTitle: boolean; + children: React.ReactNode; + title?: string; + translateTitle?: boolean; } const ListSection = React.memo(({ children, title, translateTitle }: IListSection) => ( diff --git a/app/containers/List/ListSeparator.tsx b/app/containers/List/ListSeparator.tsx index 6a78ef65ec4..db34b05ba6e 100644 --- a/app/containers/List/ListSeparator.tsx +++ b/app/containers/List/ListSeparator.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { StyleSheet, View } from 'react-native'; +import { StyleSheet, View, ViewStyle } from 'react-native'; import { themes } from '../../constants/colors'; import { withTheme } from '../../theme'; @@ -11,12 +11,12 @@ const styles = StyleSheet.create({ }); interface IListSeparator { - style: object; - theme: string; + style?: ViewStyle; + theme?: string; } const ListSeparator = React.memo(({ style, theme }: IListSeparator) => ( - + )); ListSeparator.displayName = 'List.Separator'; diff --git a/app/containers/SafeAreaView.tsx b/app/containers/SafeAreaView.tsx index 7daa3347eff..3794fdb911c 100644 --- a/app/containers/SafeAreaView.tsx +++ b/app/containers/SafeAreaView.tsx @@ -12,16 +12,16 @@ const styles = StyleSheet.create({ }); interface ISafeAreaView { - testID: string; - theme: string; - vertical: boolean; - style: object; - children: JSX.Element; + testID?: string; + theme?: string; + vertical?: boolean; + style?: object; + children: React.ReactNode; } const SafeAreaView = React.memo(({ style, children, testID, theme, vertical = true, ...props }: ISafeAreaView) => ( diff --git a/app/containers/StatusBar.tsx b/app/containers/StatusBar.tsx index da115f4edfd..5ebaf23076a 100644 --- a/app/containers/StatusBar.tsx +++ b/app/containers/StatusBar.tsx @@ -5,9 +5,9 @@ import { themes } from '../constants/colors'; import { withTheme } from '../theme'; interface IStatusBar { - theme: string; - barStyle: any; - backgroundColor: string; + theme?: string; + barStyle?: any; + backgroundColor?: string; } const StatusBar = React.memo(({ theme, barStyle, backgroundColor }: IStatusBar) => { @@ -17,7 +17,7 @@ const StatusBar = React.memo(({ theme, barStyle, backgroundColor }: IStatusBar) barStyle = 'dark-content'; } } - return ; + return ; }); export default withTheme(StatusBar); diff --git a/app/theme.tsx b/app/theme.tsx index 4accff2cd89..fdc2f7edb57 100644 --- a/app/theme.tsx +++ b/app/theme.tsx @@ -1,5 +1,6 @@ import React from 'react'; import hoistNonReactStatics from 'hoist-non-react-statics'; +import { StackNavigationOptions } from '@react-navigation/stack'; interface IThemeContextProps { theme: string; @@ -10,12 +11,17 @@ interface IThemeContextProps { setTheme?: (newTheme?: {}) => void; } +type TOptions = { + navigationOptions?: StackNavigationOptions; +}; + export const ThemeContext = React.createContext({ theme: 'light' }); -export function withTheme(Component: any) { +export function withTheme(Component: React.ComponentType & TOptions): typeof Component { const ThemedComponent = (props: any) => ( {contexts => } ); + ThemedComponent.navigationOptions = Component.navigationOptions; hoistNonReactStatics(ThemedComponent, Component); return ThemedComponent; } diff --git a/app/views/ScreenLockedView.js b/app/views/ScreenLockedView.js index 644e76ff0cb..86a102abfaa 100644 --- a/app/views/ScreenLockedView.js +++ b/app/views/ScreenLockedView.js @@ -5,15 +5,16 @@ import useDeepCompareEffect from 'use-deep-compare-effect'; import isEmpty from 'lodash/isEmpty'; import Orientation from 'react-native-orientation-locker'; -import { withTheme } from '../theme'; +import { useTheme } from '../theme'; import EventEmitter from '../utils/events'; import { LOCAL_AUTHENTICATE_EMITTER } from '../constants/localAuthentication'; import { isTablet } from '../utils/deviceInfo'; import { PasscodeEnter } from '../containers/Passcode'; -const ScreenLockedView = ({ theme }) => { +const ScreenLockedView = () => { const [visible, setVisible] = useState(false); const [data, setData] = useState({}); + const { theme } = useTheme(); useDeepCompareEffect(() => { if (!isEmpty(data)) { @@ -61,8 +62,4 @@ const ScreenLockedView = ({ theme }) => { ); }; -ScreenLockedView.propTypes = { - theme: PropTypes.string -}; - -export default withTheme(ScreenLockedView); +export default ScreenLockedView; diff --git a/app/views/ShareView/Header.tsx b/app/views/ShareView/Header.tsx index 41e5339e1e3..604eb93561e 100644 --- a/app/views/ShareView/Header.tsx +++ b/app/views/ShareView/Header.tsx @@ -5,7 +5,7 @@ import I18n from '../../i18n'; import { CustomIcon } from '../../lib/Icons'; import RocketChat from '../../lib/rocketchat'; import { themes } from '../../constants/colors'; -import { withTheme } from '../../theme'; +import { useTheme } from '../../theme'; import { isAndroid, isTablet } from '../../utils/deviceInfo'; import sharedStyles from '../Styles'; import { makeThreadName } from '../../utils/room'; @@ -37,10 +37,10 @@ const styles = StyleSheet.create({ interface IHeader { room: { prid?: string; t?: string }; thread: { id?: string }; - theme: string; } -const Header = React.memo(({ room, thread, theme }: IHeader) => { +const Header = React.memo(({ room, thread }: IHeader) => { + const { theme } = useTheme(); let type; if (thread?.id) { type = 'thread'; @@ -94,4 +94,4 @@ const Header = React.memo(({ room, thread, theme }: IHeader) => { ); }); -export default withTheme(Header); +export default Header; diff --git a/app/views/ShareView/index.tsx b/app/views/ShareView/index.tsx index e10b21483b2..de04ffbb7d5 100644 --- a/app/views/ShareView/index.tsx +++ b/app/views/ShareView/index.tsx @@ -128,11 +128,7 @@ class ShareView extends Component { if (!attachments.length && !readOnly) { options.headerRight = () => ( - + ); } @@ -363,7 +359,7 @@ class ShareView extends Component { {this.renderContent()} - + ); } diff --git a/app/views/SidebarView/SidebarItem.tsx b/app/views/SidebarView/SidebarItem.tsx index 7590e82ca74..03a3d8e9df4 100644 --- a/app/views/SidebarView/SidebarItem.tsx +++ b/app/views/SidebarView/SidebarItem.tsx @@ -8,9 +8,9 @@ import styles from './styles'; interface SidebarItemProps { left: JSX.Element; - right: JSX.Element; + right?: JSX.Element; text: string; - current: boolean; + current?: boolean; onPress(): void; testID: string; theme: string; diff --git a/app/views/SidebarView/index.tsx b/app/views/SidebarView/index.tsx index f97e3ea992d..848d90eeb33 100644 --- a/app/views/SidebarView/index.tsx +++ b/app/views/SidebarView/index.tsx @@ -44,7 +44,7 @@ interface ISidebarProps { name: string; roles: string[]; }; - theme: string; + theme?: string; loadingServer: boolean; useRealName: boolean; allowStatusMessage: boolean; @@ -176,12 +176,13 @@ class Sidebar extends Component { const routeName = isMasterDetail ? 'AdminPanelView' : 'AdminPanelStackNavigator'; return ( <> - + } + left={} onPress={() => this.sidebarNavigate(routeName)} testID='sidebar-admin' + theme={theme!} current={this.currentItemKey === routeName} /> @@ -194,30 +195,34 @@ class Sidebar extends Component { <> } + left={} onPress={() => this.sidebarNavigate('ChatsStackNavigator')} testID='sidebar-chats' + theme={theme!} current={this.currentItemKey === 'ChatsStackNavigator'} /> } + left={} onPress={() => this.sidebarNavigate('ProfileStackNavigator')} testID='sidebar-profile' + theme={theme!} current={this.currentItemKey === 'ProfileStackNavigator'} /> } + left={} onPress={() => this.sidebarNavigate('DisplayPrefStackNavigator')} testID='sidebar-display' + theme={theme!} current={this.currentItemKey === 'DisplayPrefStackNavigator'} /> } + left={} onPress={() => this.sidebarNavigate('SettingsStackNavigator')} testID='sidebar-settings' + theme={theme!} current={this.currentItemKey === 'SettingsStackNavigator'} /> {this.renderAdmin()} @@ -231,7 +236,8 @@ class Sidebar extends Component { } - right={} + theme={theme!} + right={} onPress={() => this.sidebarNavigate('StatusView')} testID='sidebar-custom-status' /> @@ -245,12 +251,12 @@ class Sidebar extends Component { return null; } return ( - + @@ -259,12 +265,12 @@ class Sidebar extends Component { - + {useRealName ? user.name : user.username} {Site_Name} @@ -273,14 +279,14 @@ class Sidebar extends Component { - + {allowStatusMessage ? this.renderCustomStatus() : null} {!isMasterDetail ? ( <> - + {this.renderNavigation()} - + ) : ( <>{this.renderAdmin()} From 13c148d7fda5d8ef1f812ef3f8c9d5a6cf6f9bbf Mon Sep 17 00:00:00 2001 From: Gerzon Z Date: Thu, 2 Dec 2021 16:24:09 -0400 Subject: [PATCH 02/14] convert SearchHeader to TypeScript, update interfaces --- app/containers/BackgroundContainer/index.tsx | 10 +++++----- app/containers/HeaderButton/HeaderButtonItem.tsx | 2 +- app/containers/List/ListIcon.tsx | 10 +++++----- app/containers/Loading.tsx | 6 +++--- app/containers/{SearchHeader.js => SearchHeader.tsx} | 11 ++++++++--- app/containers/message/index.tsx | 2 +- app/containers/message/interfaces.ts | 5 +++-- app/views/SearchMessagesView/index.tsx | 6 +++++- app/views/SettingsView/index.tsx | 2 +- 9 files changed, 32 insertions(+), 22 deletions(-) rename app/containers/{SearchHeader.js => SearchHeader.tsx} (82%) diff --git a/app/containers/BackgroundContainer/index.tsx b/app/containers/BackgroundContainer/index.tsx index fbe5d3077ab..fc26fe0abd5 100644 --- a/app/containers/BackgroundContainer/index.tsx +++ b/app/containers/BackgroundContainer/index.tsx @@ -6,9 +6,9 @@ import sharedStyles from '../../views/Styles'; import { themes } from '../../constants/colors'; interface IBackgroundContainer { - text: string; - theme: string; - loading: boolean; + text?: string; + theme?: string; + loading?: boolean; } const styles = StyleSheet.create({ @@ -35,8 +35,8 @@ const styles = StyleSheet.create({ const BackgroundContainer = ({ theme, text, loading }: IBackgroundContainer) => ( - {text ? {text} : null} - {loading ? : null} + {text ? {text} : null} + {loading ? : null} ); diff --git a/app/containers/HeaderButton/HeaderButtonItem.tsx b/app/containers/HeaderButton/HeaderButtonItem.tsx index a7c2fd009c3..1378527360f 100644 --- a/app/containers/HeaderButton/HeaderButtonItem.tsx +++ b/app/containers/HeaderButton/HeaderButtonItem.tsx @@ -8,7 +8,7 @@ import { themes } from '../../constants/colors'; import sharedStyles from '../../views/Styles'; interface IHeaderButtonItem { - title: string; + title?: string; iconName?: string; onPress(): void; testID?: string; diff --git a/app/containers/List/ListIcon.tsx b/app/containers/List/ListIcon.tsx index 7d569dce7f8..499a442cf52 100644 --- a/app/containers/List/ListIcon.tsx +++ b/app/containers/List/ListIcon.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { StyleSheet, View } from 'react-native'; +import { StyleSheet, View, ViewStyle } from 'react-native'; import { themes } from '../../constants/colors'; import { CustomIcon } from '../../lib/Icons'; @@ -7,11 +7,11 @@ import { withTheme } from '../../theme'; import { ICON_SIZE } from './constants'; interface IListIcon { - theme: string; + theme?: string; name: string; color: string; - style: object; - testID: string; + style?: ViewStyle; + testID?: string; } const styles = StyleSheet.create({ @@ -23,7 +23,7 @@ const styles = StyleSheet.create({ const ListIcon = React.memo(({ theme, name, color, style, testID }: IListIcon) => ( - + )); diff --git a/app/containers/Loading.tsx b/app/containers/Loading.tsx index 6bcc3baa0d9..cd4ed285d3f 100644 --- a/app/containers/Loading.tsx +++ b/app/containers/Loading.tsx @@ -19,7 +19,7 @@ const styles = StyleSheet.create({ interface ILoadingProps { visible: boolean; - theme: string; + theme?: string; } class Loading extends React.PureComponent { @@ -97,7 +97,7 @@ class Loading extends React.PureComponent { const opacityAnimation = opacity.interpolate({ inputRange: [0, 1], - outputRange: [0, themes[theme].backdropOpacity], + outputRange: [0, themes[theme!].backdropOpacity], extrapolate: 'clamp' }); @@ -109,7 +109,7 @@ class Loading extends React.PureComponent { { // @ts-ignore ...StyleSheet.absoluteFill, - backgroundColor: themes[theme].backdropColor, + backgroundColor: themes[theme!].backdropColor, opacity: opacityAnimation } ]} diff --git a/app/containers/SearchHeader.js b/app/containers/SearchHeader.tsx similarity index 82% rename from app/containers/SearchHeader.js rename to app/containers/SearchHeader.tsx index e231d07485a..2cabd4fe61f 100644 --- a/app/containers/SearchHeader.js +++ b/app/containers/SearchHeader.tsx @@ -20,9 +20,14 @@ const styles = StyleSheet.create({ } }); +interface ISearchHeader { + theme?: string; + onSearchChangeText?: (text: string) => void; +} + // TODO: it might be useful to refactor this component for reusage -const SearchHeader = ({ theme, onSearchChangeText }) => { - const titleColorStyle = { color: themes[theme].headerTitleColor }; +const SearchHeader = ({ theme, onSearchChangeText }: ISearchHeader) => { + const titleColorStyle = { color: themes[theme!].headerTitleColor }; const isLight = theme === 'light'; const { isLandscape } = useOrientation(); const scale = isIOS && isLandscape && !isTablet ? 0.8 : 1; @@ -35,7 +40,7 @@ const SearchHeader = ({ theme, onSearchChangeText }) => { style={[styles.title, isLight && titleColorStyle, { fontSize: titleFontSize }]} placeholder='Search' onChangeText={onSearchChangeText} - theme={theme} + theme={theme!} testID='thread-messages-view-search-header' /> diff --git a/app/containers/message/index.tsx b/app/containers/message/index.tsx index 80f5db31cc3..812437d7738 100644 --- a/app/containers/message/index.tsx +++ b/app/containers/message/index.tsx @@ -40,7 +40,7 @@ interface IMessageContainerProps { status: number; isIgnored: boolean; highlighted: boolean; - getCustomEmoji(): void; + getCustomEmoji(name: string): void; onLongPress: Function; onReactionPress: Function; onEncryptedPress: Function; diff --git a/app/containers/message/interfaces.ts b/app/containers/message/interfaces.ts index c9be40af91b..982a7958a80 100644 --- a/app/containers/message/interfaces.ts +++ b/app/containers/message/interfaces.ts @@ -51,12 +51,13 @@ export interface IMessageCallButton { } export interface IUser { - _id: string; + id: string; username: string; + token: string; name: string; } -export type UserMention = Pick; +export type UserMention = Pick; export interface IMessageContent { _id: string; diff --git a/app/views/SearchMessagesView/index.tsx b/app/views/SearchMessagesView/index.tsx index a9be999187a..8dc93146c83 100644 --- a/app/views/SearchMessagesView/index.tsx +++ b/app/views/SearchMessagesView/index.tsx @@ -52,7 +52,11 @@ interface INavigationOption { } interface ISearchMessagesViewProps extends INavigationOption { - user: { id: string }; + user: { + id: string; + username: string; + token: string; + }; baseUrl: string; serverVersion: string; customEmojis: { diff --git a/app/views/SettingsView/index.tsx b/app/views/SettingsView/index.tsx index 02c17169b19..00c6b13c058 100644 --- a/app/views/SettingsView/index.tsx +++ b/app/views/SettingsView/index.tsx @@ -182,7 +182,7 @@ class SettingsView extends React.Component { return ( - + {isMasterDetail ? ( <> From 52bbecb1dbf29f55eae0545d6db864676f475c3d Mon Sep 17 00:00:00 2001 From: Gerzon Z Date: Sun, 5 Dec 2021 17:48:42 -0400 Subject: [PATCH 03/14] Minor fixes to interfaces --- app/AppContainer.tsx | 2 +- app/containers/List/ListIcon.tsx | 2 +- app/containers/List/ListItem.tsx | 28 ++++++++++++------------ app/containers/Toast.tsx | 6 ++--- app/containers/TwoFactor/index.tsx | 8 +++---- app/{ => definitions}/navigationTypes.ts | 15 ++++++++----- app/dimensions.tsx | 5 ++++- app/share.tsx | 2 +- app/theme.tsx | 7 ++---- app/views/StatusView.tsx | 10 ++++----- 10 files changed, 45 insertions(+), 40 deletions(-) rename app/{ => definitions}/navigationTypes.ts (71%) diff --git a/app/AppContainer.tsx b/app/AppContainer.tsx index b73aaf8e3f8..441220fec33 100644 --- a/app/AppContainer.tsx +++ b/app/AppContainer.tsx @@ -3,7 +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 { SetUsernameStackParamList, StackParamList } from './definitions/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'; diff --git a/app/containers/List/ListIcon.tsx b/app/containers/List/ListIcon.tsx index 499a442cf52..72195f88661 100644 --- a/app/containers/List/ListIcon.tsx +++ b/app/containers/List/ListIcon.tsx @@ -9,7 +9,7 @@ import { ICON_SIZE } from './constants'; interface IListIcon { theme?: string; name: string; - color: string; + color?: string; style?: ViewStyle; testID?: string; } diff --git a/app/containers/List/ListItem.tsx b/app/containers/List/ListItem.tsx index a05eaf9adc6..2622b95ad9f 100644 --- a/app/containers/List/ListItem.tsx +++ b/app/containers/List/ListItem.tsx @@ -60,7 +60,7 @@ interface IListItemContent { right?: Function; disabled?: boolean; testID?: string; - theme: string; + theme?: string; color?: string; translateTitle?: boolean; translateSubtitle?: boolean; @@ -89,15 +89,15 @@ const Content = React.memo( {left ? {left()} : null} - + {translateTitle ? I18n.t(title) : title} {alert ? ( - + ) : null} {subtitle ? ( - + {translateSubtitle ? I18n.t(subtitle) : subtitle} ) : null} @@ -114,17 +114,17 @@ const Content = React.memo( interface IListItemButton { title?: string; - onPress: Function; + onPress?: Function; disabled?: boolean; - theme: string; - backgroundColor: string; + theme?: string; + backgroundColor?: string; underlayColor?: string; } -const Button = React.memo(({ onPress, backgroundColor, underlayColor, ...props }: IListItemButton) => ( +const Button: React.FC = React.memo(({ onPress, backgroundColor, underlayColor, ...props }: IListItemButton) => ( onPress(props.title)} - style={{ backgroundColor: backgroundColor || themes[props.theme].backgroundColor }} + onPress={() => onPress!(props.title)} + style={{ backgroundColor: backgroundColor || themes[props.theme!].backgroundColor }} underlayColor={underlayColor} enabled={!props.disabled} theme={props.theme}> @@ -134,16 +134,16 @@ const Button = React.memo(({ onPress, backgroundColor, underlayColor, ...props } interface IListItem { onPress: Function; - theme: string; - backgroundColor: string; + theme?: string; + backgroundColor?: string; } -const ListItem = React.memo(({ ...props }: IListItem) => { +const ListItem: React.FC = React.memo(({ ...props }: IListItem) => { if (props.onPress) { return