forked from vergnet/application-amicale
Update dialogs to use TypeScript
This commit is contained in:
parent
f95635136e
commit
98518c46b6
5 changed files with 149 additions and 166 deletions
|
@ -17,36 +17,31 @@
|
|||
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// @flow
|
||||
|
||||
import * as React from 'react';
|
||||
import {Button, Dialog, Paragraph, Portal} from 'react-native-paper';
|
||||
import i18n from 'i18n-js';
|
||||
|
||||
type PropsType = {
|
||||
visible: boolean,
|
||||
onDismiss: () => void,
|
||||
title: string | React.Node,
|
||||
message: string | React.Node,
|
||||
visible: boolean;
|
||||
onDismiss: () => void;
|
||||
title: string | React.ReactNode;
|
||||
message: string | React.ReactNode;
|
||||
};
|
||||
|
||||
class AlertDialog extends React.PureComponent<PropsType> {
|
||||
render(): React.Node {
|
||||
const {props} = this;
|
||||
return (
|
||||
<Portal>
|
||||
<Dialog visible={props.visible} onDismiss={props.onDismiss}>
|
||||
<Dialog.Title>{props.title}</Dialog.Title>
|
||||
<Dialog.Content>
|
||||
<Paragraph>{props.message}</Paragraph>
|
||||
</Dialog.Content>
|
||||
<Dialog.Actions>
|
||||
<Button onPress={props.onDismiss}>{i18n.t('dialog.ok')}</Button>
|
||||
</Dialog.Actions>
|
||||
</Dialog>
|
||||
</Portal>
|
||||
);
|
||||
}
|
||||
function AlertDialog(props: PropsType) {
|
||||
return (
|
||||
<Portal>
|
||||
<Dialog visible={props.visible} onDismiss={props.onDismiss}>
|
||||
<Dialog.Title>{props.title}</Dialog.Title>
|
||||
<Dialog.Content>
|
||||
<Paragraph>{props.message}</Paragraph>
|
||||
</Dialog.Content>
|
||||
<Dialog.Actions>
|
||||
<Button onPress={props.onDismiss}>{i18n.t('dialog.ok')}</Button>
|
||||
</Dialog.Actions>
|
||||
</Dialog>
|
||||
</Portal>
|
||||
);
|
||||
}
|
||||
|
||||
export default AlertDialog;
|
|
@ -1,90 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 - 2020 Arnaud Vergnet.
|
||||
*
|
||||
* This file is part of Campus INSAT.
|
||||
*
|
||||
* Campus INSAT is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Campus INSAT is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// @flow
|
||||
|
||||
import * as React from 'react';
|
||||
import i18n from 'i18n-js';
|
||||
import {ERROR_TYPE} from '../../utils/WebData';
|
||||
import AlertDialog from './AlertDialog';
|
||||
|
||||
type PropsType = {
|
||||
visible: boolean,
|
||||
onDismiss: () => void,
|
||||
errorCode: number,
|
||||
};
|
||||
|
||||
class ErrorDialog extends React.PureComponent<PropsType> {
|
||||
title: string;
|
||||
|
||||
message: string;
|
||||
|
||||
generateMessage() {
|
||||
const {props} = this;
|
||||
this.title = i18n.t('errors.title');
|
||||
switch (props.errorCode) {
|
||||
case ERROR_TYPE.BAD_CREDENTIALS:
|
||||
this.message = i18n.t('errors.badCredentials');
|
||||
break;
|
||||
case ERROR_TYPE.BAD_TOKEN:
|
||||
this.message = i18n.t('errors.badToken');
|
||||
break;
|
||||
case ERROR_TYPE.NO_CONSENT:
|
||||
this.message = i18n.t('errors.noConsent');
|
||||
break;
|
||||
case ERROR_TYPE.TOKEN_SAVE:
|
||||
this.message = i18n.t('errors.tokenSave');
|
||||
break;
|
||||
case ERROR_TYPE.TOKEN_RETRIEVE:
|
||||
this.message = i18n.t('errors.unknown');
|
||||
break;
|
||||
case ERROR_TYPE.BAD_INPUT:
|
||||
this.message = i18n.t('errors.badInput');
|
||||
break;
|
||||
case ERROR_TYPE.FORBIDDEN:
|
||||
this.message = i18n.t('errors.forbidden');
|
||||
break;
|
||||
case ERROR_TYPE.CONNECTION_ERROR:
|
||||
this.message = i18n.t('errors.connectionError');
|
||||
break;
|
||||
case ERROR_TYPE.SERVER_ERROR:
|
||||
this.message = i18n.t('errors.serverError');
|
||||
break;
|
||||
default:
|
||||
this.message = i18n.t('errors.unknown');
|
||||
break;
|
||||
}
|
||||
this.message += `\n\nCode ${props.errorCode}`;
|
||||
}
|
||||
|
||||
render(): React.Node {
|
||||
this.generateMessage();
|
||||
const {props} = this;
|
||||
return (
|
||||
<AlertDialog
|
||||
visible={props.visible}
|
||||
onDismiss={props.onDismiss}
|
||||
title={this.title}
|
||||
message={this.message}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ErrorDialog;
|
80
src/components/Dialogs/ErrorDialog.tsx
Normal file
80
src/components/Dialogs/ErrorDialog.tsx
Normal file
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright (c) 2019 - 2020 Arnaud Vergnet.
|
||||
*
|
||||
* This file is part of Campus INSAT.
|
||||
*
|
||||
* Campus INSAT is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Campus INSAT is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import * as React from 'react';
|
||||
import i18n from 'i18n-js';
|
||||
import {ERROR_TYPE} from '../../utils/WebData';
|
||||
import AlertDialog from './AlertDialog';
|
||||
|
||||
type PropsType = {
|
||||
visible: boolean;
|
||||
onDismiss: () => void;
|
||||
errorCode: number;
|
||||
};
|
||||
|
||||
function ErrorDialog(props: PropsType) {
|
||||
let title: string;
|
||||
let message: string;
|
||||
|
||||
title = i18n.t('errors.title');
|
||||
switch (props.errorCode) {
|
||||
case ERROR_TYPE.BAD_CREDENTIALS:
|
||||
message = i18n.t('errors.badCredentials');
|
||||
break;
|
||||
case ERROR_TYPE.BAD_TOKEN:
|
||||
message = i18n.t('errors.badToken');
|
||||
break;
|
||||
case ERROR_TYPE.NO_CONSENT:
|
||||
message = i18n.t('errors.noConsent');
|
||||
break;
|
||||
case ERROR_TYPE.TOKEN_SAVE:
|
||||
message = i18n.t('errors.tokenSave');
|
||||
break;
|
||||
case ERROR_TYPE.TOKEN_RETRIEVE:
|
||||
message = i18n.t('errors.unknown');
|
||||
break;
|
||||
case ERROR_TYPE.BAD_INPUT:
|
||||
message = i18n.t('errors.badInput');
|
||||
break;
|
||||
case ERROR_TYPE.FORBIDDEN:
|
||||
message = i18n.t('errors.forbidden');
|
||||
break;
|
||||
case ERROR_TYPE.CONNECTION_ERROR:
|
||||
message = i18n.t('errors.connectionError');
|
||||
break;
|
||||
case ERROR_TYPE.SERVER_ERROR:
|
||||
message = i18n.t('errors.serverError');
|
||||
break;
|
||||
default:
|
||||
message = i18n.t('errors.unknown');
|
||||
break;
|
||||
}
|
||||
message += `\n\nCode ${props.errorCode}`;
|
||||
|
||||
return (
|
||||
<AlertDialog
|
||||
visible={props.visible}
|
||||
onDismiss={props.onDismiss}
|
||||
title={title}
|
||||
message={message}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default ErrorDialog;
|
|
@ -17,8 +17,6 @@
|
|||
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// @flow
|
||||
|
||||
import * as React from 'react';
|
||||
import {
|
||||
ActivityIndicator,
|
||||
|
@ -30,20 +28,23 @@ import {
|
|||
import i18n from 'i18n-js';
|
||||
|
||||
type PropsType = {
|
||||
visible: boolean,
|
||||
onDismiss?: () => void,
|
||||
onAccept?: () => Promise<void>, // async function to be executed
|
||||
title?: string,
|
||||
titleLoading?: string,
|
||||
message?: string,
|
||||
startLoading?: boolean,
|
||||
visible: boolean;
|
||||
onDismiss?: () => void;
|
||||
onAccept?: () => Promise<void>; // async function to be executed
|
||||
title?: string;
|
||||
titleLoading?: string;
|
||||
message?: string;
|
||||
startLoading?: boolean;
|
||||
};
|
||||
|
||||
type StateType = {
|
||||
loading: boolean,
|
||||
loading: boolean;
|
||||
};
|
||||
|
||||
class LoadingConfirmDialog extends React.PureComponent<PropsType, StateType> {
|
||||
export default class LoadingConfirmDialog extends React.PureComponent<
|
||||
PropsType,
|
||||
StateType
|
||||
> {
|
||||
static defaultProps = {
|
||||
onDismiss: () => {},
|
||||
onAccept: (): Promise<void> => {
|
||||
|
@ -71,14 +72,16 @@ class LoadingConfirmDialog extends React.PureComponent<PropsType, StateType> {
|
|||
onClickAccept = () => {
|
||||
const {props} = this;
|
||||
this.setState({loading: true});
|
||||
if (props.onAccept != null) props.onAccept().then(this.hideLoading);
|
||||
if (props.onAccept != null) {
|
||||
props.onAccept().then(this.hideLoading);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Waits for fade out animations to finish before hiding loading
|
||||
* @returns {TimeoutID}
|
||||
* @returns {NodeJS.Timeout}
|
||||
*/
|
||||
hideLoading = (): TimeoutID =>
|
||||
hideLoading = (): NodeJS.Timeout =>
|
||||
setTimeout(() => {
|
||||
this.setState({loading: false});
|
||||
}, 200);
|
||||
|
@ -88,10 +91,12 @@ class LoadingConfirmDialog extends React.PureComponent<PropsType, StateType> {
|
|||
*/
|
||||
onDismiss = () => {
|
||||
const {state, props} = this;
|
||||
if (!state.loading && props.onDismiss != null) props.onDismiss();
|
||||
if (!state.loading && props.onDismiss != null) {
|
||||
props.onDismiss();
|
||||
}
|
||||
};
|
||||
|
||||
render(): React.Node {
|
||||
render() {
|
||||
const {state, props} = this;
|
||||
return (
|
||||
<Portal>
|
||||
|
@ -121,5 +126,3 @@ class LoadingConfirmDialog extends React.PureComponent<PropsType, StateType> {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default LoadingConfirmDialog;
|
|
@ -17,28 +17,26 @@
|
|||
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// @flow
|
||||
|
||||
import * as React from 'react';
|
||||
import {Button, Dialog, Paragraph, Portal} from 'react-native-paper';
|
||||
import {FlatList} from 'react-native';
|
||||
|
||||
export type OptionsDialogButtonType = {
|
||||
title: string,
|
||||
icon?: string,
|
||||
onPress: () => void,
|
||||
title: string;
|
||||
icon?: string;
|
||||
onPress: () => void;
|
||||
};
|
||||
|
||||
type PropsType = {
|
||||
visible: boolean,
|
||||
title: string,
|
||||
message: string,
|
||||
buttons: Array<OptionsDialogButtonType>,
|
||||
onDismiss: () => void,
|
||||
visible: boolean;
|
||||
title: string;
|
||||
message: string;
|
||||
buttons: Array<OptionsDialogButtonType>;
|
||||
onDismiss: () => void;
|
||||
};
|
||||
|
||||
class OptionsDialog extends React.PureComponent<PropsType> {
|
||||
getButtonRender = ({item}: {item: OptionsDialogButtonType}): React.Node => {
|
||||
function OptionsDialog(props: PropsType) {
|
||||
const getButtonRender = ({item}: {item: OptionsDialogButtonType}) => {
|
||||
return (
|
||||
<Button onPress={item.onPress} icon={item.icon}>
|
||||
{item.title}
|
||||
|
@ -46,35 +44,32 @@ class OptionsDialog extends React.PureComponent<PropsType> {
|
|||
);
|
||||
};
|
||||
|
||||
keyExtractor = (item: OptionsDialogButtonType): string => {
|
||||
const keyExtractor = (item: OptionsDialogButtonType): string => {
|
||||
if (item.icon != null) {
|
||||
return item.title + item.icon;
|
||||
}
|
||||
return item.title;
|
||||
};
|
||||
|
||||
render(): React.Node {
|
||||
const {props} = this;
|
||||
return (
|
||||
<Portal>
|
||||
<Dialog visible={props.visible} onDismiss={props.onDismiss}>
|
||||
<Dialog.Title>{props.title}</Dialog.Title>
|
||||
<Dialog.Content>
|
||||
<Paragraph>{props.message}</Paragraph>
|
||||
</Dialog.Content>
|
||||
<Dialog.Actions>
|
||||
<FlatList
|
||||
data={props.buttons}
|
||||
renderItem={this.getButtonRender}
|
||||
keyExtractor={this.keyExtractor}
|
||||
horizontal
|
||||
inverted
|
||||
/>
|
||||
</Dialog.Actions>
|
||||
</Dialog>
|
||||
</Portal>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Portal>
|
||||
<Dialog visible={props.visible} onDismiss={props.onDismiss}>
|
||||
<Dialog.Title>{props.title}</Dialog.Title>
|
||||
<Dialog.Content>
|
||||
<Paragraph>{props.message}</Paragraph>
|
||||
</Dialog.Content>
|
||||
<Dialog.Actions>
|
||||
<FlatList
|
||||
data={props.buttons}
|
||||
renderItem={getButtonRender}
|
||||
keyExtractor={keyExtractor}
|
||||
horizontal
|
||||
inverted
|
||||
/>
|
||||
</Dialog.Actions>
|
||||
</Dialog>
|
||||
</Portal>
|
||||
);
|
||||
}
|
||||
|
||||
export default OptionsDialog;
|
Loading…
Reference in a new issue