2020-06-15 14:00:46 +00:00
|
|
|
import React, { useContext } from 'react';
|
2020-06-26 20:22:56 +00:00
|
|
|
import { Dimensions } from 'react-native';
|
2020-06-15 14:00:46 +00:00
|
|
|
import { NavigationContainer } from '@react-navigation/native';
|
2019-12-04 16:39:53 +00:00
|
|
|
import { AppearanceProvider } from 'react-native-appearance';
|
2020-06-15 14:00:46 +00:00
|
|
|
import { createStackNavigator } from '@react-navigation/stack';
|
2019-07-18 17:44:02 +00:00
|
|
|
import { Provider } from 'react-redux';
|
|
|
|
|
2021-09-13 20:41:05 +00:00
|
|
|
import { defaultTheme, newThemeState, subscribeTheme, unsubscribeTheme } from './utils/theme';
|
2020-08-19 17:14:22 +00:00
|
|
|
import UserPreferences from './lib/userPreferences';
|
2019-07-29 16:33:28 +00:00
|
|
|
import Navigation from './lib/ShareNavigation';
|
2019-07-18 17:44:02 +00:00
|
|
|
import store from './lib/createStore';
|
2020-06-15 14:00:46 +00:00
|
|
|
import { supportSystemTheme } from './utils/deviceInfo';
|
2021-09-13 20:41:05 +00:00
|
|
|
import { defaultHeader, getActiveRouteName, navigationTheme, themedHeader } from './utils/navigation';
|
2019-12-04 16:39:53 +00:00
|
|
|
import RocketChat, { THEME_PREFERENCES_KEY } from './lib/rocketchat';
|
|
|
|
import { ThemeContext } from './theme';
|
2020-05-08 17:04:37 +00:00
|
|
|
import { localAuthenticate } from './utils/localAuthentication';
|
2022-01-12 12:54:04 +00:00
|
|
|
import { IThemePreference } from './definitions/ITheme';
|
2020-05-08 17:04:37 +00:00
|
|
|
import ScreenLockedView from './views/ScreenLockedView';
|
2020-06-15 14:00:46 +00:00
|
|
|
// Outside Stack
|
|
|
|
import WithoutServersView from './views/WithoutServersView';
|
|
|
|
// Inside Stack
|
|
|
|
import ShareListView from './views/ShareListView';
|
|
|
|
import ShareView from './views/ShareView';
|
|
|
|
import SelectServerView from './views/SelectServerView';
|
|
|
|
import { setCurrentScreen } from './utils/log';
|
|
|
|
import AuthLoadingView from './views/AuthLoadingView';
|
2020-06-26 20:22:56 +00:00
|
|
|
import { DimensionsContext } from './dimensions';
|
|
|
|
import debounce from './utils/debounce';
|
2022-01-17 16:10:39 +00:00
|
|
|
import { ShareInsideStackParamList, ShareOutsideStackParamList, ShareAppStackParamList } from './definitions/navigationTypes';
|
2020-06-15 14:00:46 +00:00
|
|
|
|
2021-09-13 20:41:05 +00:00
|
|
|
interface IDimensions {
|
|
|
|
width: number;
|
|
|
|
height: number;
|
|
|
|
scale: number;
|
|
|
|
fontScale: number;
|
|
|
|
}
|
|
|
|
|
|
|
|
interface IState {
|
|
|
|
theme: string;
|
2022-01-12 12:54:04 +00:00
|
|
|
themePreferences: IThemePreference;
|
2021-09-13 20:41:05 +00:00
|
|
|
root: any;
|
|
|
|
width: number;
|
|
|
|
height: number;
|
|
|
|
scale: number;
|
|
|
|
fontScale: number;
|
|
|
|
}
|
|
|
|
|
2021-12-03 19:27:57 +00:00
|
|
|
const Inside = createStackNavigator<ShareInsideStackParamList>();
|
2020-06-15 14:00:46 +00:00
|
|
|
const InsideStack = () => {
|
|
|
|
const { theme } = useContext(ThemeContext);
|
|
|
|
|
|
|
|
const screenOptions = {
|
|
|
|
...defaultHeader,
|
|
|
|
...themedHeader(theme)
|
|
|
|
};
|
2021-09-13 20:41:05 +00:00
|
|
|
screenOptions.headerStyle = { ...screenOptions.headerStyle, height: 57 };
|
2020-06-15 14:00:46 +00:00
|
|
|
|
|
|
|
return (
|
|
|
|
<Inside.Navigator screenOptions={screenOptions}>
|
2021-09-13 20:41:05 +00:00
|
|
|
<Inside.Screen name='ShareListView' component={ShareListView} />
|
|
|
|
<Inside.Screen name='ShareView' component={ShareView} />
|
|
|
|
<Inside.Screen name='SelectServerView' component={SelectServerView} options={SelectServerView.navigationOptions} />
|
2020-06-15 14:00:46 +00:00
|
|
|
</Inside.Navigator>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2021-12-03 19:27:57 +00:00
|
|
|
const Outside = createStackNavigator<ShareOutsideStackParamList>();
|
2020-06-15 14:00:46 +00:00
|
|
|
const OutsideStack = () => {
|
|
|
|
const { theme } = useContext(ThemeContext);
|
|
|
|
|
|
|
|
return (
|
|
|
|
<Outside.Navigator screenOptions={{ ...defaultHeader, ...themedHeader(theme) }}>
|
2021-12-03 19:27:57 +00:00
|
|
|
<Outside.Screen name='WithoutServersView' component={WithoutServersView} options={WithoutServersView.navigationOptions} />
|
2020-06-15 14:00:46 +00:00
|
|
|
</Outside.Navigator>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
// App
|
2021-12-03 19:27:57 +00:00
|
|
|
const Stack = createStackNavigator<ShareAppStackParamList>();
|
2021-09-13 20:41:05 +00:00
|
|
|
export const App = ({ root }: any) => (
|
2020-06-26 20:22:56 +00:00
|
|
|
<Stack.Navigator screenOptions={{ headerShown: false, animationEnabled: false }}>
|
2020-06-15 14:00:46 +00:00
|
|
|
<>
|
2021-09-13 20:41:05 +00:00
|
|
|
{!root ? <Stack.Screen name='AuthLoading' component={AuthLoadingView} /> : null}
|
|
|
|
{root === 'outside' ? <Stack.Screen name='OutsideStack' component={OutsideStack} /> : null}
|
|
|
|
{root === 'inside' ? <Stack.Screen name='InsideStack' component={InsideStack} /> : null}
|
2020-06-15 14:00:46 +00:00
|
|
|
</>
|
|
|
|
</Stack.Navigator>
|
|
|
|
);
|
|
|
|
|
2021-09-13 20:41:05 +00:00
|
|
|
class Root extends React.Component<{}, IState> {
|
|
|
|
constructor(props: any) {
|
2019-07-18 17:44:02 +00:00
|
|
|
super(props);
|
2021-09-13 20:41:05 +00:00
|
|
|
const { width, height, scale, fontScale } = Dimensions.get('screen');
|
2019-10-02 12:18:08 +00:00
|
|
|
this.state = {
|
2019-12-04 16:39:53 +00:00
|
|
|
theme: defaultTheme(),
|
|
|
|
themePreferences: {
|
|
|
|
currentTheme: supportSystemTheme() ? 'automatic' : 'light',
|
2021-07-12 18:05:09 +00:00
|
|
|
darkLevel: 'black'
|
2020-06-15 14:00:46 +00:00
|
|
|
},
|
2020-06-26 20:22:56 +00:00
|
|
|
root: '',
|
|
|
|
width,
|
|
|
|
height,
|
2020-10-30 13:59:44 +00:00
|
|
|
scale,
|
|
|
|
fontScale
|
2019-10-02 12:18:08 +00:00
|
|
|
};
|
2019-07-29 16:33:28 +00:00
|
|
|
this.init();
|
|
|
|
}
|
|
|
|
|
2021-12-03 19:27:57 +00:00
|
|
|
componentWillUnmount(): void {
|
2019-12-04 16:41:37 +00:00
|
|
|
RocketChat.closeShareExtension();
|
2019-12-04 16:39:53 +00:00
|
|
|
unsubscribeTheme();
|
|
|
|
}
|
|
|
|
|
2021-09-13 20:41:05 +00:00
|
|
|
init = async () => {
|
|
|
|
UserPreferences.getMapAsync(THEME_PREFERENCES_KEY).then((theme: any) => this.setTheme(theme));
|
2020-08-19 17:14:22 +00:00
|
|
|
|
2021-03-18 13:18:33 +00:00
|
|
|
const currentServer = await UserPreferences.getStringAsync(RocketChat.CURRENT_SERVER);
|
2019-07-29 16:33:28 +00:00
|
|
|
|
2021-03-18 13:18:33 +00:00
|
|
|
if (currentServer) {
|
2020-05-08 17:04:37 +00:00
|
|
|
await localAuthenticate(currentServer);
|
2020-06-15 14:00:46 +00:00
|
|
|
this.setState({ root: 'inside' });
|
2019-07-29 16:33:28 +00:00
|
|
|
await RocketChat.shareExtensionInit(currentServer);
|
|
|
|
} else {
|
2020-06-15 14:00:46 +00:00
|
|
|
this.setState({ root: 'outside' });
|
2019-07-29 16:33:28 +00:00
|
|
|
}
|
2020-06-15 14:00:46 +00:00
|
|
|
|
2020-07-02 17:10:11 +00:00
|
|
|
const state = Navigation.navigationRef.current?.getRootState();
|
2020-06-15 14:00:46 +00:00
|
|
|
const currentRouteName = getActiveRouteName(state);
|
|
|
|
Navigation.routeNameRef.current = currentRouteName;
|
|
|
|
setCurrentScreen(currentRouteName);
|
2021-09-13 20:41:05 +00:00
|
|
|
};
|
2019-07-18 17:44:02 +00:00
|
|
|
|
2019-12-04 16:39:53 +00:00
|
|
|
setTheme = (newTheme = {}) => {
|
|
|
|
// change theme state
|
2021-09-13 20:41:05 +00:00
|
|
|
this.setState(
|
2022-01-12 12:54:04 +00:00
|
|
|
prevState => newThemeState(prevState, newTheme as IThemePreference),
|
2021-09-13 20:41:05 +00:00
|
|
|
() => {
|
|
|
|
const { themePreferences } = this.state;
|
|
|
|
// subscribe to Appearance changes
|
|
|
|
subscribeTheme(themePreferences, this.setTheme);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
};
|
2019-12-04 16:39:53 +00:00
|
|
|
|
2020-06-26 20:22:56 +00:00
|
|
|
// Dimensions update fires twice
|
2021-09-13 20:41:05 +00:00
|
|
|
onDimensionsChange = debounce(({ window: { width, height, scale, fontScale } }: { window: IDimensions }) => {
|
|
|
|
this.setDimensions({ width, height, scale, fontScale });
|
|
|
|
});
|
2020-06-26 20:22:56 +00:00
|
|
|
|
2021-09-13 20:41:05 +00:00
|
|
|
setDimensions = ({ width, height, scale, fontScale }: IDimensions) => {
|
2020-10-30 13:59:44 +00:00
|
|
|
this.setState({
|
2021-09-13 20:41:05 +00:00
|
|
|
width,
|
|
|
|
height,
|
|
|
|
scale,
|
|
|
|
fontScale
|
2020-10-30 13:59:44 +00:00
|
|
|
});
|
2021-09-13 20:41:05 +00:00
|
|
|
};
|
2020-06-26 20:22:56 +00:00
|
|
|
|
2019-07-18 17:44:02 +00:00
|
|
|
render() {
|
2021-09-13 20:41:05 +00:00
|
|
|
const { theme, root, width, height, scale, fontScale } = this.state;
|
2020-06-15 14:00:46 +00:00
|
|
|
const navTheme = navigationTheme(theme);
|
2019-07-18 17:44:02 +00:00
|
|
|
return (
|
2019-12-04 16:39:53 +00:00
|
|
|
<AppearanceProvider>
|
2020-06-15 14:00:46 +00:00
|
|
|
<Provider store={store}>
|
|
|
|
<ThemeContext.Provider value={{ theme }}>
|
2020-06-26 20:22:56 +00:00
|
|
|
<DimensionsContext.Provider
|
|
|
|
value={{
|
|
|
|
width,
|
|
|
|
height,
|
|
|
|
scale,
|
2020-10-30 13:59:44 +00:00
|
|
|
fontScale,
|
2020-06-26 20:22:56 +00:00
|
|
|
setDimensions: this.setDimensions
|
2021-09-13 20:41:05 +00:00
|
|
|
}}>
|
2020-06-26 20:22:56 +00:00
|
|
|
<NavigationContainer
|
|
|
|
theme={navTheme}
|
|
|
|
ref={Navigation.navigationRef}
|
2021-09-13 20:41:05 +00:00
|
|
|
onStateChange={state => {
|
2020-06-26 20:22:56 +00:00
|
|
|
const previousRouteName = Navigation.routeNameRef.current;
|
|
|
|
const currentRouteName = getActiveRouteName(state);
|
|
|
|
if (previousRouteName !== currentRouteName) {
|
|
|
|
setCurrentScreen(currentRouteName);
|
|
|
|
}
|
|
|
|
Navigation.routeNameRef.current = currentRouteName;
|
2021-09-13 20:41:05 +00:00
|
|
|
}}>
|
2020-06-26 20:22:56 +00:00
|
|
|
<App root={root} />
|
|
|
|
</NavigationContainer>
|
|
|
|
<ScreenLockedView />
|
|
|
|
</DimensionsContext.Provider>
|
2020-06-15 14:00:46 +00:00
|
|
|
</ThemeContext.Provider>
|
|
|
|
</Provider>
|
2019-12-04 16:39:53 +00:00
|
|
|
</AppearanceProvider>
|
2019-07-18 17:44:02 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default Root;
|