forked from vergnet/application-amicale
		
	Improved authenticated screens states
This commit is contained in:
		
							parent
							
								
									c5e79f45c3
								
							
						
					
					
						commit
						4406efaf41
					
				
					 4 changed files with 111 additions and 28 deletions
				
			
		|  | @ -1,6 +1,6 @@ | |||
| import * as React from 'react'; | ||||
| import {View} from "react-native"; | ||||
| import {Text} from 'react-native-paper'; | ||||
| import {ActivityIndicator, Text, withTheme} from 'react-native-paper'; | ||||
| import ConnectionManager from "../managers/ConnectionManager"; | ||||
| 
 | ||||
| type Props = { | ||||
|  | @ -14,39 +14,97 @@ type State = { | |||
|     loading: boolean, | ||||
| } | ||||
| 
 | ||||
| export default class AuthenticatedScreen extends React.Component<Props, State> { | ||||
| class AuthenticatedScreen extends React.Component<Props, State> { | ||||
| 
 | ||||
|     state = { | ||||
|         loading: true, | ||||
|     }; | ||||
| 
 | ||||
|     currentUserToken: string; | ||||
|     connectionManager: ConnectionManager; | ||||
|     data: Object; | ||||
|     colors: Object; | ||||
| 
 | ||||
|     constructor(props) { | ||||
|         super(props); | ||||
|         this.colors = props.theme.colors; | ||||
|         this.connectionManager = ConnectionManager.getInstance(); | ||||
|         this.props.navigation.addListener('focus', this.onScreenFocus.bind(this)); | ||||
| 
 | ||||
|         this.fetchData(); | ||||
|     } | ||||
| 
 | ||||
|     onScreenFocus() { | ||||
|         if (this.currentUserToken !== this.connectionManager.getToken()) | ||||
|             this.fetchData(); | ||||
|     } | ||||
| 
 | ||||
|     fetchData() { | ||||
|         if (!this.state.loading) | ||||
|             this.setState({loading: true}); | ||||
|         this.connectionManager.isLoggedIn() | ||||
|             .then(() => { | ||||
|                 this.setState({loading: false}); | ||||
|                 this.connectionManager.authenticatedRequest(this.props.link) | ||||
|                     .then((data) => { | ||||
|                         console.log(data); | ||||
|                         this.onFinishedLoading(data); | ||||
|                     }) | ||||
|                     .catch((error) => { | ||||
|                         console.log(error); | ||||
|                         this.onFinishedLoading(undefined); | ||||
|                     }); | ||||
|             }) | ||||
|             .catch(() => { | ||||
|                 this.props.navigation.navigate('LoginScreen'); | ||||
|                 this.onFinishedLoading(undefined); | ||||
|             }); | ||||
|     } | ||||
| 
 | ||||
|     onFinishedLoading(data: Object) { | ||||
|         this.data = data; | ||||
|         this.currentUserToken = data !== undefined | ||||
|             ? this.connectionManager.getToken() | ||||
|             : ''; | ||||
|         this.setState({loading: false}); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Gets the loading indicator | ||||
|      * | ||||
|      * @return {*} | ||||
|      */ | ||||
|     getRenderLoading() { | ||||
|         return ( | ||||
|             <View style={{ | ||||
|                 backgroundColor: this.colors.background, | ||||
|                 position: 'absolute', | ||||
|                 top: 0, | ||||
|                 right: 0, | ||||
|                 width: '100%', | ||||
|                 height: '100%', | ||||
|                 flex: 1, | ||||
|                 alignItems: 'center', | ||||
|                 justifyContent: 'center' | ||||
|             }}> | ||||
|                 <ActivityIndicator | ||||
|                     animating={true} | ||||
|                     size={'large'} | ||||
|                     color={this.colors.primary}/> | ||||
|             </View> | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     getErrorRender() { | ||||
|         return <Text>ERROR</Text>; | ||||
|     } | ||||
| 
 | ||||
|     render() { | ||||
|         return ( | ||||
|             this.state.loading | ||||
|                 ? <View><Text>LOADING</Text></View> | ||||
|                 : this.props.renderFunction() | ||||
|                 ? this.getRenderLoading() | ||||
|                 : (this.data !== undefined | ||||
|                 ? this.props.renderFunction(this.data) | ||||
|                 : this.getErrorRender()) | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| export default withTheme(AuthenticatedScreen); | ||||
|  |  | |||
|  | @ -29,11 +29,6 @@ class SideBar extends React.PureComponent<Props, State> { | |||
| 
 | ||||
|     dataSet: Array<Object>; | ||||
| 
 | ||||
|     state = { | ||||
|         active: 'Home', | ||||
|         isLoggedIn: false, | ||||
|     }; | ||||
| 
 | ||||
|     getRenderItem: Function; | ||||
|     colors: Object; | ||||
| 
 | ||||
|  | @ -61,18 +56,19 @@ class SideBar extends React.PureComponent<Props, State> { | |||
|                 icon: "login", | ||||
|                 onlyWhenLoggedOut: true, | ||||
|             }, | ||||
|             { | ||||
|                 name: 'DISCONNECT', | ||||
|                 action: () => this.onClickDisconnect(), | ||||
|                 icon: "logout", | ||||
|                 onlyWhenLoggedIn: true, | ||||
|             }, | ||||
|             { | ||||
|                 name: 'PROFILE', | ||||
|                 route: "ProfileScreen", | ||||
|                 icon: "circle", | ||||
|                 onlyWhenLoggedIn: true, | ||||
|             }, | ||||
|             { | ||||
|                 name: 'DISCONNECT', | ||||
|                 route: 'disconnect', | ||||
|                 action: () => this.onClickDisconnect(), | ||||
|                 icon: "logout", | ||||
|                 onlyWhenLoggedIn: true, | ||||
|             }, | ||||
|             { | ||||
|                 name: i18n.t('sidenav.divider2'), | ||||
|                 route: "Divider2" | ||||
|  | @ -150,15 +146,29 @@ class SideBar extends React.PureComponent<Props, State> { | |||
|         this.getRenderItem = this.getRenderItem.bind(this); | ||||
|         this.colors = props.theme.colors; | ||||
|         ConnectionManager.getInstance().setLoginCallback((value) => this.onLoginStateChange(value)); | ||||
|         this.state = { | ||||
|             active: 'Home', | ||||
|             isLoggedIn: false, | ||||
|         }; | ||||
|         ConnectionManager.getInstance().isLoggedIn() | ||||
|     } | ||||
| 
 | ||||
|     onClickDisconnect() { | ||||
|         console.log('coucou'); | ||||
|         Alert.alert( | ||||
|             'DISCONNECT', | ||||
|             'DISCONNECT?', | ||||
|             [ | ||||
|                 {text: 'YES', onPress: () => ConnectionManager.getInstance().disconnect()}, | ||||
|                 { | ||||
|                     text: 'YES', onPress: () => { | ||||
|                         ConnectionManager.getInstance().disconnect() | ||||
|                             .then(() => { | ||||
|                                 this.props.navigation.reset({ | ||||
|                                     index: 0, | ||||
|                                     routes: [{name: 'Main'}], | ||||
|                                 }); | ||||
|                             }); | ||||
|                     } | ||||
|                 }, | ||||
|                 {text: 'NO', undefined}, | ||||
|             ], | ||||
|             {cancelable: false}, | ||||
|  | @ -176,7 +186,6 @@ class SideBar extends React.PureComponent<Props, State> { | |||
|      * @param item The item pressed | ||||
|      */ | ||||
|     onListItemPress(item: Object) { | ||||
|         console.log(item.action); | ||||
|         if (item.link !== undefined) | ||||
|             openBrowser(item.link, this.colors.primary); | ||||
|         else if (item.action !== undefined) | ||||
|  |  | |||
|  | @ -29,6 +29,10 @@ export default class ConnectionManager { | |||
|             ConnectionManager.instance; | ||||
|     } | ||||
| 
 | ||||
|     getToken() { | ||||
|         return this.#token; | ||||
|     } | ||||
| 
 | ||||
|     onLoginStateChange(newState: boolean) { | ||||
|         this.loginCallback(newState); | ||||
|     } | ||||
|  | @ -44,8 +48,11 @@ export default class ConnectionManager { | |||
|             else { | ||||
|                 SecureStore.getItemAsync('token') | ||||
|                     .then((token) => { | ||||
|                         this.onLoginStateChange(true); | ||||
|                         resolve(token); | ||||
|                         if (token !== null) { | ||||
|                             this.onLoginStateChange(true); | ||||
|                             resolve(token); | ||||
|                         } else | ||||
|                             reject(false); | ||||
|                     }) | ||||
|                     .catch(error => { | ||||
|                         reject(false); | ||||
|  | @ -82,8 +89,16 @@ export default class ConnectionManager { | |||
|     } | ||||
| 
 | ||||
|     async disconnect() { | ||||
|         SecureStore.deleteItemAsync('token'); // TODO use promise
 | ||||
|         this.onLoginStateChange(false); | ||||
|         return new Promise((resolve, reject) => { | ||||
|             SecureStore.deleteItemAsync('token') | ||||
|                 .then(() => { | ||||
|                     this.onLoginStateChange(false); | ||||
|                     resolve(true); | ||||
|                 }) | ||||
|                 .catch((error) => { | ||||
|                     reject(false); | ||||
|                 }); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     async connect(email: string, password: string) { | ||||
|  |  | |||
|  | @ -24,9 +24,10 @@ class ProfileScreen extends React.Component<Props, State> { | |||
|     } | ||||
| 
 | ||||
|     getScreen(data: Object) { | ||||
| 
 | ||||
|         return ( | ||||
|             <View> | ||||
|                 <Text>PAGE</Text> | ||||
|                 <Text>{data.first_name} {Math.random()}</Text> | ||||
|             </View> | ||||
|         ) | ||||
|     } | ||||
|  | @ -36,7 +37,7 @@ class ProfileScreen extends React.Component<Props, State> { | |||
|             <AuthenticatedScreen | ||||
|                 {...this.props} | ||||
|                 link={'https://www.amicale-insat.fr/api/user/profile'} | ||||
|                 renderFunction={() => this.getScreen()} | ||||
|                 renderFunction={(data) => this.getScreen(data)} | ||||
|             /> | ||||
|         ); | ||||
|     } | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue