Chore: Migrate App/index.tsx to hooks

This commit is contained in:
Reinaldo Neto 2022-07-29 01:19:44 -03:00
parent a965465af3
commit c18960efb7
2 changed files with 90 additions and 105 deletions

View File

@ -1,4 +1,4 @@
import React from 'react'; import React, { useEffect, useRef, useState } from 'react';
import { Dimensions, Linking } from 'react-native'; import { Dimensions, Linking } from 'react-native';
import { AppearanceProvider } from 'react-native-appearance'; import { AppearanceProvider } from 'react-native-appearance';
import { KeyCommandsEmitter } from 'react-native-keycommands'; import { KeyCommandsEmitter } from 'react-native-keycommands';
@ -24,7 +24,7 @@ import parseQuery from './lib/methods/helpers/parseQuery';
import { initializePushNotifications, onNotification } from './lib/notifications'; import { initializePushNotifications, onNotification } from './lib/notifications';
import store from './lib/store'; import store from './lib/store';
import { initStore } from './lib/store/auxStore'; import { initStore } from './lib/store/auxStore';
import { ThemeContext, TSupportedThemes } from './theme'; import { ThemeContext } from './theme';
import { debounce, isTablet } from './lib/methods/helpers'; import { debounce, isTablet } from './lib/methods/helpers';
import EventEmitter from './lib/methods/helpers/events'; import EventEmitter from './lib/methods/helpers/events';
import { toggleAnalyticsEventsReport, toggleCrashErrorsReport } from './lib/methods/helpers/log'; import { toggleAnalyticsEventsReport, toggleCrashErrorsReport } from './lib/methods/helpers/log';
@ -49,15 +49,6 @@ interface IDimensions {
fontScale: number; fontScale: number;
} }
interface IState {
theme: TSupportedThemes;
themePreferences: IThemePreference;
width: number;
height: number;
scale: number;
fontScale: number;
}
const parseDeepLinking = (url: string) => { const parseDeepLinking = (url: string) => {
if (url) { if (url) {
url = url.replace(/rocketchat:\/\/|https:\/\/go.rocket.chat\//, ''); url = url.replace(/rocketchat:\/\/|https:\/\/go.rocket.chat\//, '');
@ -81,35 +72,32 @@ const parseDeepLinking = (url: string) => {
return null; return null;
}; };
export default class Root extends React.Component<{}, IState> { const Root = () => {
private listenerTimeout!: any; const { width: widthWindow, height: heightWindow, scale: scaleWindow, fontScale: fontScaleWindow } = Dimensions.get('window');
const [theme, setTheme] = useState(getTheme(initialTheme()));
const [themePreferences, setThemePreferences] = useState(initialTheme());
const [width, setWidth] = useState(widthWindow);
const [height, setHeight] = useState(heightWindow);
const [scale, setScale] = useState(scaleWindow);
const [fontScale, setFontScale] = useState(fontScaleWindow);
private onKeyCommands: any; const listenerTimeout = useRef<any>();
const onKeyCommands = useRef<any>();
constructor(props: any) { useEffect(() => {
super(props); init();
this.init();
if (!isFDroidBuild) { if (!isFDroidBuild) {
this.initCrashReport(); initCrashReport();
} }
const { width, height, scale, fontScale } = Dimensions.get('window');
const theme = initialTheme(); const theme = initialTheme();
this.state = {
theme: getTheme(theme),
themePreferences: theme,
width,
height,
scale,
fontScale
};
if (isTablet) { if (isTablet) {
this.initTablet(); initTablet();
} }
setNativeTheme(theme); setNativeTheme(theme);
} }, []);
componentDidMount() { useEffect(() => {
this.listenerTimeout = setTimeout(() => { listenerTimeout.current = setTimeout(() => {
Linking.addEventListener('url', ({ url }) => { Linking.addEventListener('url', ({ url }) => {
const parsedDeepLinkingURL = parseDeepLinking(url); const parsedDeepLinkingURL = parseDeepLinking(url);
if (parsedDeepLinkingURL) { if (parsedDeepLinkingURL) {
@ -117,21 +105,21 @@ export default class Root extends React.Component<{}, IState> {
} }
}); });
}, 5000); }, 5000);
Dimensions.addEventListener('change', this.onDimensionsChange); Dimensions.addEventListener('change', onDimensionsChange);
}
componentWillUnmount() { return () => {
clearTimeout(this.listenerTimeout); clearTimeout(listenerTimeout.current);
Dimensions.removeEventListener('change', this.onDimensionsChange); Dimensions.removeEventListener('change', onDimensionsChange);
unsubscribeTheme(); unsubscribeTheme();
if (this.onKeyCommands && this.onKeyCommands.remove) { if (onKeyCommands.current && onKeyCommands.current.remove) {
this.onKeyCommands.remove(); onKeyCommands.current.remove();
} }
} };
}, []);
init = async () => { const init = async () => {
store.dispatch(appInitLocalSettings()); store.dispatch(appInitLocalSettings());
// Open app from push notification // Open app from push notification
@ -153,54 +141,54 @@ export default class Root extends React.Component<{}, IState> {
store.dispatch(appInit()); store.dispatch(appInit());
}; };
getMasterDetail = (width: number) => { const getMasterDetail = (width: number) => {
if (!isTablet) { if (!isTablet) {
return false; return false;
} }
return width > MIN_WIDTH_MASTER_DETAIL_LAYOUT; return width > MIN_WIDTH_MASTER_DETAIL_LAYOUT;
}; };
setMasterDetail = (width: number) => { const setMasterDetail = (width: number) => {
const isMasterDetail = this.getMasterDetail(width); const isMasterDetail = getMasterDetail(width);
store.dispatch(setMasterDetailAction(isMasterDetail)); store.dispatch(setMasterDetailAction(isMasterDetail));
}; };
// Dimensions update fires twice // Dimensions update fires twice
onDimensionsChange = debounce(({ window: { width, height, scale, fontScale } }: { window: IDimensions }) => { const onDimensionsChange = debounce(({ window: { width, height, scale, fontScale } }: { window: IDimensions }) => {
this.setDimensions({ setDimensions({
width, width,
height, height,
scale, scale,
fontScale fontScale
}); });
this.setMasterDetail(width); setMasterDetail(width);
}); });
setTheme = (newTheme = {}) => { const setThemeFunction = (newThemeObject = {}) => {
// change theme state const { theme: newTheme, themePreferences: newThemePreferences } = newThemeState(
this.setState( themePreferences,
prevState => newThemeState(prevState, newTheme as IThemePreference), newThemeObject as IThemePreference
() => {
const { themePreferences } = this.state;
// subscribe to Appearance changes
subscribeTheme(themePreferences, this.setTheme);
}
); );
setThemePreferences(newThemePreferences);
setTheme(newTheme);
subscribeTheme(themePreferences, setThemeFunction);
}; };
setDimensions = ({ width, height, scale, fontScale }: IDimensions) => { const setDimensions = ({ width, height, scale, fontScale }: IDimensions) => {
this.setState({ width, height, scale, fontScale }); setWidth(width);
setHeight(height);
setScale(scale);
setFontScale(fontScale);
}; };
initTablet = () => { const initTablet = () => {
const { width } = this.state; setMasterDetail(width);
this.setMasterDetail(width); onKeyCommands.current = KeyCommandsEmitter.addListener('onKeyCommand', (command: ICommand) => {
this.onKeyCommands = KeyCommandsEmitter.addListener('onKeyCommand', (command: ICommand) => {
EventEmitter.emit(KEY_COMMAND, { event: command }); EventEmitter.emit(KEY_COMMAND, { event: command });
}); });
}; };
initCrashReport = () => { const initCrashReport = () => {
getAllowCrashReport().then(allowCrashReport => { getAllowCrashReport().then(allowCrashReport => {
toggleCrashErrorsReport(allowCrashReport); toggleCrashErrorsReport(allowCrashReport);
}); });
@ -209,44 +197,41 @@ export default class Root extends React.Component<{}, IState> {
}); });
}; };
render() { return (
const { themePreferences, theme, width, height, scale, fontScale } = this.state; <SafeAreaProvider initialMetrics={initialWindowMetrics} style={{ backgroundColor: themes[theme].backgroundColor }}>
return ( <AppearanceProvider>
<SafeAreaProvider <Provider store={store}>
initialMetrics={initialWindowMetrics} <ThemeContext.Provider
style={{ backgroundColor: themes[this.state.theme].backgroundColor }}> value={{
<AppearanceProvider> theme,
<Provider store={store}> themePreferences,
<ThemeContext.Provider setTheme: setThemeFunction,
colors: colors[theme]
}}>
<DimensionsContext.Provider
value={{ value={{
theme, width,
themePreferences, height,
setTheme: this.setTheme, scale,
colors: colors[theme] fontScale,
setDimensions
}}> }}>
<DimensionsContext.Provider <GestureHandlerRootView style={{ flex: 1 }}>
value={{ <ActionSheetProvider>
width, <AppContainer />
height, <TwoFactor />
scale, <ScreenLockedView />
fontScale, <ChangePasscodeView />
setDimensions: this.setDimensions <InAppNotification />
}}> <Toast />
<GestureHandlerRootView style={{ flex: 1 }}> </ActionSheetProvider>
<ActionSheetProvider> </GestureHandlerRootView>
<AppContainer /> </DimensionsContext.Provider>
<TwoFactor /> </ThemeContext.Provider>
<ScreenLockedView /> </Provider>
<ChangePasscodeView /> </AppearanceProvider>
<InAppNotification /> </SafeAreaProvider>
<Toast /> );
</ActionSheetProvider> };
</GestureHandlerRootView>
</DimensionsContext.Provider> export default Root;
</ThemeContext.Provider>
</Provider>
</AppearanceProvider>
</SafeAreaProvider>
);
}
}

View File

@ -36,10 +36,10 @@ export const getTheme = (themePreferences: IThemePreference): TSupportedThemes =
return theme === 'dark' ? darkLevel : 'light'; return theme === 'dark' ? darkLevel : 'light';
}; };
export const newThemeState = (prevState: { themePreferences: IThemePreference }, newTheme: IThemePreference) => { export const newThemeState = (prevthemePreferences: IThemePreference, newTheme: IThemePreference) => {
// new theme preferences // new theme preferences
const themePreferences = { const themePreferences = {
...prevState.themePreferences, ...prevthemePreferences,
...newTheme ...newTheme
}; };
// set new state of themePreferences // set new state of themePreferences