Update misc screens to use TypeScript

This commit is contained in:
Arnaud Vergnet 2020-09-22 21:58:09 +02:00
parent b8e7272d2c
commit 4d0df7a5b7
5 changed files with 219 additions and 233 deletions

View file

@ -22,7 +22,7 @@ import {TouchableRipple, useTheme} from 'react-native-paper';
import {Dimensions, Image, View} from 'react-native'; import {Dimensions, Image, View} from 'react-native';
type PropsType = { type PropsType = {
image: string; image?: string | number;
isActive: boolean; isActive: boolean;
onPress: () => void; onPress: () => void;
}; };
@ -51,13 +51,17 @@ function DashboardEditPreviewItem(props: PropsType) {
width: itemSize, width: itemSize,
height: itemSize, height: itemSize,
}}> }}>
<Image {props.image ? (
source={{uri: props.image}} <Image
style={{ source={
width: '100%', typeof props.image === 'string' ? {uri: props.image} : props.image
height: '100%', }
}} style={{
/> width: '100%',
height: '100%',
}}
/>
) : null}
</View> </View>
</TouchableRipple> </TouchableRipple>
); );

View file

@ -1,179 +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 {Avatar, Button, Card, Paragraph, withTheme} from 'react-native-paper';
import i18n from 'i18n-js';
import {Linking, View} from 'react-native';
import CollapsibleScrollView from '../../components/Collapsible/CollapsibleScrollView';
import type {CardTitleIconPropsType} from '../../constants/PaperStyles';
const links = {
bugsGit: 'https://git.etud.insa-toulouse.fr/vergnet/application-amicale/',
trello: 'https://trello.com/b/RMej49Uq/application-campus-insa',
facebook: 'https://www.facebook.com/campus.insat',
feedbackMail: `mailto:app@amicale-insat.fr?subject=[FEEDBACK] Application CAMPUS
&body=Coucou Arnaud j'ai du feedback\n\n\n\nBien cordialement.`,
feedbackDiscord: 'https://discord.gg/W8MeTec',
};
class FeedbackScreen extends React.Component<null> {
/**
* Gets link buttons
*
* @returns {*}
*/
static getButtons(isFeedback: boolean): React.Node {
return (
<Card.Actions
style={{
flex: 1,
flexWrap: 'wrap',
}}>
{isFeedback ? (
<View
style={{
flex: 1,
flexWrap: 'wrap',
flexDirection: 'row',
width: '100%',
}}>
<Button
icon="email"
mode="contained"
style={{
marginLeft: 'auto',
marginRight: 'auto',
marginTop: 5,
}}
onPress={() => {
Linking.openURL(links.feedbackMail);
}}>
MAIL
</Button>
<Button
icon="facebook"
mode="contained"
color="#2e88fe"
style={{
marginLeft: 'auto',
marginRight: 'auto',
marginTop: 5,
}}
onPress={() => {
Linking.openURL(links.facebook);
}}>
Facebook
</Button>
<Button
icon="discord"
mode="contained"
color="#7289da"
style={{
marginLeft: 'auto',
marginRight: 'auto',
marginTop: 5,
}}
onPress={() => {
Linking.openURL(links.feedbackDiscord);
}}>
Discord
</Button>
</View>
) : (
<View
style={{
flex: 1,
flexWrap: 'wrap',
flexDirection: 'row',
width: '100%',
}}>
<Button
icon="git"
mode="contained"
color="#609927"
style={{
marginLeft: 'auto',
marginRight: 'auto',
marginTop: 5,
}}
onPress={() => {
Linking.openURL(links.bugsGit);
}}>
GITETUD
</Button>
<Button
icon="calendar"
mode="contained"
color="#026AA7"
style={{
marginLeft: 'auto',
marginRight: 'auto',
marginTop: 5,
}}
onPress={() => {
Linking.openURL(links.trello);
}}>
TRELLO
</Button>
</View>
)}
</Card.Actions>
);
}
render(): React.Node {
return (
<CollapsibleScrollView style={{padding: 5}}>
<Card>
<Card.Title
title={i18n.t('screens.feedback.feedback')}
subtitle={i18n.t('screens.feedback.feedbackSubtitle')}
left={(iconProps: CardTitleIconPropsType): React.Node => (
<Avatar.Icon size={iconProps.size} icon="comment" />
)}
/>
<Card.Content>
<Paragraph>
{i18n.t('screens.feedback.feedbackDescription')}
</Paragraph>
</Card.Content>
{FeedbackScreen.getButtons(true)}
<Card.Title
title={i18n.t('screens.feedback.contribute')}
subtitle={i18n.t('screens.feedback.contributeSubtitle')}
left={(iconProps: CardTitleIconPropsType): React.Node => (
<Avatar.Icon size={iconProps.size} icon="handshake" />
)}
/>
<Card.Content>
<Paragraph>
{i18n.t('screens.feedback.contributeDescription')}
</Paragraph>
</Card.Content>
{FeedbackScreen.getButtons(false)}
</Card>
</CollapsibleScrollView>
);
}
}
export default withTheme(FeedbackScreen);

View file

@ -0,0 +1,169 @@
/*
* 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 {Avatar, Button, Card, Paragraph, withTheme} from 'react-native-paper';
import i18n from 'i18n-js';
import {Linking, View} from 'react-native';
import CollapsibleScrollView from '../../components/Collapsible/CollapsibleScrollView';
const links = {
bugsGit: 'https://git.etud.insa-toulouse.fr/vergnet/application-amicale/',
trello: 'https://trello.com/b/RMej49Uq/application-campus-insa',
facebook: 'https://www.facebook.com/campus.insat',
feedbackMail: `mailto:app@amicale-insat.fr?subject=[FEEDBACK] Application CAMPUS
&body=Coucou Arnaud j'ai du feedback\n\n\n\nBien cordialement.`,
feedbackDiscord: 'https://discord.gg/W8MeTec',
};
function getButtons(isFeedback: boolean) {
return (
<Card.Actions
style={{
flex: 1,
flexWrap: 'wrap',
}}>
{isFeedback ? (
<View
style={{
flex: 1,
flexWrap: 'wrap',
flexDirection: 'row',
width: '100%',
}}>
<Button
icon="email"
mode="contained"
style={{
marginLeft: 'auto',
marginRight: 'auto',
marginTop: 5,
}}
onPress={() => {
Linking.openURL(links.feedbackMail);
}}>
MAIL
</Button>
<Button
icon="facebook"
mode="contained"
color="#2e88fe"
style={{
marginLeft: 'auto',
marginRight: 'auto',
marginTop: 5,
}}
onPress={() => {
Linking.openURL(links.facebook);
}}>
Facebook
</Button>
<Button
icon="discord"
mode="contained"
color="#7289da"
style={{
marginLeft: 'auto',
marginRight: 'auto',
marginTop: 5,
}}
onPress={() => {
Linking.openURL(links.feedbackDiscord);
}}>
Discord
</Button>
</View>
) : (
<View
style={{
flex: 1,
flexWrap: 'wrap',
flexDirection: 'row',
width: '100%',
}}>
<Button
icon="git"
mode="contained"
color="#609927"
style={{
marginLeft: 'auto',
marginRight: 'auto',
marginTop: 5,
}}
onPress={() => {
Linking.openURL(links.bugsGit);
}}>
GITETUD
</Button>
<Button
icon="calendar"
mode="contained"
color="#026AA7"
style={{
marginLeft: 'auto',
marginRight: 'auto',
marginTop: 5,
}}
onPress={() => {
Linking.openURL(links.trello);
}}>
TRELLO
</Button>
</View>
)}
</Card.Actions>
);
}
function FeedbackScreen() {
return (
<CollapsibleScrollView style={{padding: 5}}>
<Card>
<Card.Title
title={i18n.t('screens.feedback.feedback')}
subtitle={i18n.t('screens.feedback.feedbackSubtitle')}
left={(iconProps) => (
<Avatar.Icon size={iconProps.size} icon="comment" />
)}
/>
<Card.Content>
<Paragraph>
{i18n.t('screens.feedback.feedbackDescription')}
</Paragraph>
</Card.Content>
{getButtons(true)}
<Card.Title
title={i18n.t('screens.feedback.contribute')}
subtitle={i18n.t('screens.feedback.contributeSubtitle')}
left={(iconProps) => (
<Avatar.Icon size={iconProps.size} icon="handshake" />
)}
/>
<Card.Content>
<Paragraph>
{i18n.t('screens.feedback.contributeDescription')}
</Paragraph>
</Card.Content>
{getButtons(false)}
</Card>
</CollapsibleScrollView>
);
}
export default withTheme(FeedbackScreen);

View file

@ -17,11 +17,9 @@
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>. * along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
*/ */
// @flow
import * as React from 'react'; import * as React from 'react';
import {StackNavigationProp} from '@react-navigation/stack'; import {StackNavigationProp} from '@react-navigation/stack';
import {Button, Card, Paragraph, withTheme} from 'react-native-paper'; import {Button, Card, Paragraph} from 'react-native-paper';
import {FlatList} from 'react-native'; import {FlatList} from 'react-native';
import {View} from 'react-native-animatable'; import {View} from 'react-native-animatable';
import i18n from 'i18n-js'; import i18n from 'i18n-js';
@ -30,20 +28,19 @@ import type {
ServiceItemType, ServiceItemType,
} from '../../../managers/ServicesManager'; } from '../../../managers/ServicesManager';
import DashboardManager from '../../../managers/DashboardManager'; import DashboardManager from '../../../managers/DashboardManager';
import DashboardItem from '../../../components/Home/EventDashboardItem';
import DashboardEditAccordion from '../../../components/Lists/DashboardEdit/DashboardEditAccordion'; import DashboardEditAccordion from '../../../components/Lists/DashboardEdit/DashboardEditAccordion';
import DashboardEditPreviewItem from '../../../components/Lists/DashboardEdit/DashboardEditPreviewItem'; import DashboardEditPreviewItem from '../../../components/Lists/DashboardEdit/DashboardEditPreviewItem';
import AsyncStorageManager from '../../../managers/AsyncStorageManager'; import AsyncStorageManager from '../../../managers/AsyncStorageManager';
import CollapsibleFlatList from '../../../components/Collapsible/CollapsibleFlatList'; import CollapsibleFlatList from '../../../components/Collapsible/CollapsibleFlatList';
type PropsType = { type PropsType = {
navigation: StackNavigationProp, navigation: StackNavigationProp<any>;
}; };
type StateType = { type StateType = {
currentDashboard: Array<ServiceItemType | null>, currentDashboard: Array<ServiceItemType | null>;
currentDashboardIdList: Array<string>, currentDashboardIdList: Array<string>;
activeItem: number, activeItem: number;
}; };
/** /**
@ -75,13 +72,13 @@ class DashboardEditScreen extends React.Component<PropsType, StateType> {
item, item,
index, index,
}: { }: {
item: DashboardItem, item: ServiceItemType | null;
index: number, index: number;
}): React.Node => { }) => {
const {activeItem} = this.state; const {activeItem} = this.state;
return ( return (
<DashboardEditPreviewItem <DashboardEditPreviewItem
image={item.image} image={item?.image}
onPress={() => { onPress={() => {
this.setState({activeItem: index}); this.setState({activeItem: index});
}} }}
@ -90,7 +87,7 @@ class DashboardEditScreen extends React.Component<PropsType, StateType> {
); );
}; };
getDashboard(content: Array<DashboardItem>): React.Node { getDashboard(content: Array<ServiceItemType | null>) {
return ( return (
<FlatList <FlatList
data={content} data={content}
@ -106,7 +103,7 @@ class DashboardEditScreen extends React.Component<PropsType, StateType> {
); );
} }
getRenderItem = ({item}: {item: ServiceCategoryType}): React.Node => { getRenderItem = ({item}: {item: ServiceCategoryType}) => {
const {currentDashboardIdList} = this.state; const {currentDashboardIdList} = this.state;
return ( return (
<DashboardEditAccordion <DashboardEditAccordion
@ -117,7 +114,7 @@ class DashboardEditScreen extends React.Component<PropsType, StateType> {
); );
}; };
getListHeader(): React.Node { getListHeader() {
const {currentDashboard} = this.state; const {currentDashboard} = this.state;
return ( return (
<Card style={{margin: 5}}> <Card style={{margin: 5}}>
@ -170,7 +167,7 @@ class DashboardEditScreen extends React.Component<PropsType, StateType> {
); );
}; };
render(): React.Node { render() {
return ( return (
<CollapsibleFlatList <CollapsibleFlatList
data={this.content} data={this.content}
@ -182,4 +179,4 @@ class DashboardEditScreen extends React.Component<PropsType, StateType> {
} }
} }
export default withTheme(DashboardEditScreen); export default DashboardEditScreen;

View file

@ -17,8 +17,6 @@
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>. * along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
*/ */
// @flow
import * as React from 'react'; import * as React from 'react';
import {View} from 'react-native'; import {View} from 'react-native';
import i18n from 'i18n-js'; import i18n from 'i18n-js';
@ -32,24 +30,22 @@ import {
} from 'react-native-paper'; } from 'react-native-paper';
import {Appearance} from 'react-native-appearance'; import {Appearance} from 'react-native-appearance';
import {StackNavigationProp} from '@react-navigation/stack'; import {StackNavigationProp} from '@react-navigation/stack';
import type {CustomThemeType} from '../../../managers/ThemeManager';
import ThemeManager from '../../../managers/ThemeManager'; import ThemeManager from '../../../managers/ThemeManager';
import AsyncStorageManager from '../../../managers/AsyncStorageManager'; import AsyncStorageManager from '../../../managers/AsyncStorageManager';
import CustomSlider from '../../../components/Overrides/CustomSlider'; import CustomSlider from '../../../components/Overrides/CustomSlider';
import CollapsibleScrollView from '../../../components/Collapsible/CollapsibleScrollView'; import CollapsibleScrollView from '../../../components/Collapsible/CollapsibleScrollView';
import type {ListIconPropsType} from '../../../constants/PaperStyles';
type PropsType = { type PropsType = {
navigation: StackNavigationProp, navigation: StackNavigationProp<any>;
theme: CustomThemeType, theme: ReactNativePaper.Theme;
}; };
type StateType = { type StateType = {
nightMode: boolean, nightMode: boolean;
nightModeFollowSystem: boolean, nightModeFollowSystem: boolean;
startScreenPickerSelected: string, startScreenPickerSelected: string;
selectedWash: string, selectedWash: string;
isDebugUnlocked: boolean, isDebugUnlocked: boolean;
}; };
/** /**
@ -61,14 +57,15 @@ class SettingsScreen extends React.Component<PropsType, StateType> {
/** /**
* Loads user preferences into state * Loads user preferences into state
*/ */
constructor() { constructor(props: PropsType) {
super(); super(props);
const notifReminder = AsyncStorageManager.getString( const notifReminder = AsyncStorageManager.getString(
AsyncStorageManager.PREFERENCES.proxiwashNotifications.key, AsyncStorageManager.PREFERENCES.proxiwashNotifications.key,
); );
this.savedNotificationReminder = parseInt(notifReminder, 10); this.savedNotificationReminder = parseInt(notifReminder, 10);
if (Number.isNaN(this.savedNotificationReminder)) if (Number.isNaN(this.savedNotificationReminder)) {
this.savedNotificationReminder = 0; this.savedNotificationReminder = 0;
}
this.state = { this.state = {
nightMode: ThemeManager.getNightMode(), nightMode: ThemeManager.getNightMode(),
@ -120,7 +117,7 @@ class SettingsScreen extends React.Component<PropsType, StateType> {
* *
* @returns {React.Node} * @returns {React.Node}
*/ */
getProxiwashNotifPicker(): React.Node { getProxiwashNotifPicker() {
const {theme} = this.props; const {theme} = this.props;
return ( return (
<CustomSlider <CustomSlider
@ -141,7 +138,7 @@ class SettingsScreen extends React.Component<PropsType, StateType> {
* *
* @returns {React.Node} * @returns {React.Node}
*/ */
getProxiwashChangePicker(): React.Node { getProxiwashChangePicker() {
const {selectedWash} = this.state; const {selectedWash} = this.state;
return ( return (
<RadioButton.Group <RadioButton.Group
@ -164,7 +161,7 @@ class SettingsScreen extends React.Component<PropsType, StateType> {
* *
* @returns {React.Node} * @returns {React.Node}
*/ */
getStartScreenPicker(): React.Node { getStartScreenPicker() {
const {startScreenPickerSelected} = this.state; const {startScreenPickerSelected} = this.state;
return ( return (
<ToggleButton.Row <ToggleButton.Row
@ -220,17 +217,15 @@ class SettingsScreen extends React.Component<PropsType, StateType> {
title: string, title: string,
subtitle: string, subtitle: string,
state: boolean, state: boolean,
): React.Node { ) {
return ( return (
<List.Item <List.Item
title={title} title={title}
description={subtitle} description={subtitle}
left={(props: ListIconPropsType): React.Node => ( left={(props) => (
<List.Icon color={props.color} style={props.style} icon={icon} /> <List.Icon color={props.color} style={props.style} icon={icon} />
)} )}
right={(): React.Node => ( right={() => <Switch value={state} onValueChange={onPressCallback} />}
<Switch value={state} onValueChange={onPressCallback} />
)}
/> />
); );
} }
@ -241,7 +236,7 @@ class SettingsScreen extends React.Component<PropsType, StateType> {
title: string, title: string,
subtitle: string, subtitle: string,
onLongPress?: () => void, onLongPress?: () => void,
): React.Node { ) {
const {navigation} = this.props; const {navigation} = this.props;
return ( return (
<List.Item <List.Item
@ -250,10 +245,10 @@ class SettingsScreen extends React.Component<PropsType, StateType> {
onPress={() => { onPress={() => {
navigation.navigate(route); navigation.navigate(route);
}} }}
left={(props: ListIconPropsType): React.Node => ( left={(props) => (
<List.Icon color={props.color} style={props.style} icon={icon} /> <List.Icon color={props.color} style={props.style} icon={icon} />
)} )}
right={(props: ListIconPropsType): React.Node => ( right={(props) => (
<List.Icon <List.Icon
color={props.color} color={props.color}
style={props.style} style={props.style}
@ -291,7 +286,7 @@ class SettingsScreen extends React.Component<PropsType, StateType> {
); );
}; };
render(): React.Node { render() {
const {nightModeFollowSystem, nightMode, isDebugUnlocked} = this.state; const {nightModeFollowSystem, nightMode, isDebugUnlocked} = this.state;
return ( return (
<CollapsibleScrollView> <CollapsibleScrollView>
@ -322,7 +317,7 @@ class SettingsScreen extends React.Component<PropsType, StateType> {
<List.Item <List.Item
title={i18n.t('screens.settings.startScreen')} title={i18n.t('screens.settings.startScreen')}
description={i18n.t('screens.settings.startScreenSub')} description={i18n.t('screens.settings.startScreenSub')}
left={(props: ListIconPropsType): React.Node => ( left={(props) => (
<List.Icon <List.Icon
color={props.color} color={props.color}
style={props.style} style={props.style}
@ -345,7 +340,7 @@ class SettingsScreen extends React.Component<PropsType, StateType> {
<List.Item <List.Item
title={i18n.t('screens.settings.proxiwashNotifReminder')} title={i18n.t('screens.settings.proxiwashNotifReminder')}
description={i18n.t('screens.settings.proxiwashNotifReminderSub')} description={i18n.t('screens.settings.proxiwashNotifReminderSub')}
left={(props: ListIconPropsType): React.Node => ( left={(props) => (
<List.Icon <List.Icon
color={props.color} color={props.color}
style={props.style} style={props.style}
@ -359,7 +354,7 @@ class SettingsScreen extends React.Component<PropsType, StateType> {
<List.Item <List.Item
title={i18n.t('screens.settings.proxiwashChangeWash')} title={i18n.t('screens.settings.proxiwashChangeWash')}
description={i18n.t('screens.settings.proxiwashChangeWashSub')} description={i18n.t('screens.settings.proxiwashChangeWashSub')}
left={(props: ListIconPropsType): React.Node => ( left={(props) => (
<List.Icon <List.Icon
color={props.color} color={props.color}
style={props.style} style={props.style}