Improved authenticated screens states

This commit is contained in:
Arnaud Vergnet 2020-03-31 18:40:06 +02:00
parent c5e79f45c3
commit 4406efaf41
4 changed files with 111 additions and 28 deletions

View file

@ -1,6 +1,6 @@
import * as React from 'react'; import * as React from 'react';
import {View} from "react-native"; import {View} from "react-native";
import {Text} from 'react-native-paper'; import {ActivityIndicator, Text, withTheme} from 'react-native-paper';
import ConnectionManager from "../managers/ConnectionManager"; import ConnectionManager from "../managers/ConnectionManager";
type Props = { type Props = {
@ -14,39 +14,97 @@ type State = {
loading: boolean, loading: boolean,
} }
export default class AuthenticatedScreen extends React.Component<Props, State> { class AuthenticatedScreen extends React.Component<Props, State> {
state = { state = {
loading: true, loading: true,
}; };
currentUserToken: string;
connectionManager: ConnectionManager; connectionManager: ConnectionManager;
data: Object;
colors: Object;
constructor(props) { constructor(props) {
super(props); super(props);
this.colors = props.theme.colors;
this.connectionManager = ConnectionManager.getInstance(); 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() this.connectionManager.isLoggedIn()
.then(() => { .then(() => {
this.setState({loading: false});
this.connectionManager.authenticatedRequest(this.props.link) this.connectionManager.authenticatedRequest(this.props.link)
.then((data) => { .then((data) => {
console.log(data); this.onFinishedLoading(data);
}) })
.catch((error) => { .catch((error) => {
console.log(error); this.onFinishedLoading(undefined);
}); });
}) })
.catch(() => { .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() { render() {
return ( return (
this.state.loading this.state.loading
? <View><Text>LOADING</Text></View> ? this.getRenderLoading()
: this.props.renderFunction() : (this.data !== undefined
? this.props.renderFunction(this.data)
: this.getErrorRender())
); );
} }
} }
export default withTheme(AuthenticatedScreen);

View file

@ -29,11 +29,6 @@ class SideBar extends React.PureComponent<Props, State> {
dataSet: Array<Object>; dataSet: Array<Object>;
state = {
active: 'Home',
isLoggedIn: false,
};
getRenderItem: Function; getRenderItem: Function;
colors: Object; colors: Object;
@ -61,18 +56,19 @@ class SideBar extends React.PureComponent<Props, State> {
icon: "login", icon: "login",
onlyWhenLoggedOut: true, onlyWhenLoggedOut: true,
}, },
{
name: 'DISCONNECT',
action: () => this.onClickDisconnect(),
icon: "logout",
onlyWhenLoggedIn: true,
},
{ {
name: 'PROFILE', name: 'PROFILE',
route: "ProfileScreen", route: "ProfileScreen",
icon: "circle", icon: "circle",
onlyWhenLoggedIn: true, onlyWhenLoggedIn: true,
}, },
{
name: 'DISCONNECT',
route: 'disconnect',
action: () => this.onClickDisconnect(),
icon: "logout",
onlyWhenLoggedIn: true,
},
{ {
name: i18n.t('sidenav.divider2'), name: i18n.t('sidenav.divider2'),
route: "Divider2" route: "Divider2"
@ -150,15 +146,29 @@ class SideBar extends React.PureComponent<Props, State> {
this.getRenderItem = this.getRenderItem.bind(this); this.getRenderItem = this.getRenderItem.bind(this);
this.colors = props.theme.colors; this.colors = props.theme.colors;
ConnectionManager.getInstance().setLoginCallback((value) => this.onLoginStateChange(value)); ConnectionManager.getInstance().setLoginCallback((value) => this.onLoginStateChange(value));
this.state = {
active: 'Home',
isLoggedIn: false,
};
ConnectionManager.getInstance().isLoggedIn()
} }
onClickDisconnect() { onClickDisconnect() {
console.log('coucou');
Alert.alert( Alert.alert(
'DISCONNECT', 'DISCONNECT',
'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}, {text: 'NO', undefined},
], ],
{cancelable: false}, {cancelable: false},
@ -176,7 +186,6 @@ class SideBar extends React.PureComponent<Props, State> {
* @param item The item pressed * @param item The item pressed
*/ */
onListItemPress(item: Object) { onListItemPress(item: Object) {
console.log(item.action);
if (item.link !== undefined) if (item.link !== undefined)
openBrowser(item.link, this.colors.primary); openBrowser(item.link, this.colors.primary);
else if (item.action !== undefined) else if (item.action !== undefined)

View file

@ -29,6 +29,10 @@ export default class ConnectionManager {
ConnectionManager.instance; ConnectionManager.instance;
} }
getToken() {
return this.#token;
}
onLoginStateChange(newState: boolean) { onLoginStateChange(newState: boolean) {
this.loginCallback(newState); this.loginCallback(newState);
} }
@ -44,8 +48,11 @@ export default class ConnectionManager {
else { else {
SecureStore.getItemAsync('token') SecureStore.getItemAsync('token')
.then((token) => { .then((token) => {
if (token !== null) {
this.onLoginStateChange(true); this.onLoginStateChange(true);
resolve(token); resolve(token);
} else
reject(false);
}) })
.catch(error => { .catch(error => {
reject(false); reject(false);
@ -82,8 +89,16 @@ export default class ConnectionManager {
} }
async disconnect() { async disconnect() {
SecureStore.deleteItemAsync('token'); // TODO use promise return new Promise((resolve, reject) => {
SecureStore.deleteItemAsync('token')
.then(() => {
this.onLoginStateChange(false); this.onLoginStateChange(false);
resolve(true);
})
.catch((error) => {
reject(false);
});
});
} }
async connect(email: string, password: string) { async connect(email: string, password: string) {

View file

@ -24,9 +24,10 @@ class ProfileScreen extends React.Component<Props, State> {
} }
getScreen(data: Object) { getScreen(data: Object) {
return ( return (
<View> <View>
<Text>PAGE</Text> <Text>{data.first_name} {Math.random()}</Text>
</View> </View>
) )
} }
@ -36,7 +37,7 @@ class ProfileScreen extends React.Component<Props, State> {
<AuthenticatedScreen <AuthenticatedScreen
{...this.props} {...this.props}
link={'https://www.amicale-insat.fr/api/user/profile'} link={'https://www.amicale-insat.fr/api/user/profile'}
renderFunction={() => this.getScreen()} renderFunction={(data) => this.getScreen(data)}
/> />
); );
} }