forked from vergnet/application-amicale
Update component overrides and intro slides to use TypeScript
This commit is contained in:
parent
18f8c64302
commit
acc4f8cdcc
14 changed files with 370 additions and 420 deletions
17
package-lock.json
generated
17
package-lock.json
generated
|
@ -2608,6 +2608,17 @@
|
|||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"@types/react-native-calendars": {
|
||||
"version": "1.20.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-native-calendars/-/react-native-calendars-1.20.10.tgz",
|
||||
"integrity": "sha512-bmWlkFa/6SNF98aM9rjKMGUOSDb15VBsfxBW5oo/iJ5tm5THf+eAGlxH72hGZFqJpr93plBs+ctkRVHQA7fx1w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/react": "*",
|
||||
"@types/react-native": "*",
|
||||
"@types/xdate": "*"
|
||||
}
|
||||
},
|
||||
"@types/react-native-vector-icons": {
|
||||
"version": "6.4.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-native-vector-icons/-/react-native-vector-icons-6.4.6.tgz",
|
||||
|
@ -2632,6 +2643,12 @@
|
|||
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz",
|
||||
"integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw=="
|
||||
},
|
||||
"@types/xdate": {
|
||||
"version": "0.8.31",
|
||||
"resolved": "https://registry.npmjs.org/@types/xdate/-/xdate-0.8.31.tgz",
|
||||
"integrity": "sha512-iZYRKKK8UZXoepNh2kwK6TPITMj/dwdv0NzNi9DFMt2foGkU7h+ncaCpGsdD2fp/CXMs9dxPAzV9uddFy7c4QA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/yargs": {
|
||||
"version": "15.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz",
|
||||
|
|
|
@ -67,9 +67,10 @@
|
|||
"@babel/runtime": "^7.11.0",
|
||||
"@react-native-community/eslint-config": "^1.1.0",
|
||||
"@types/i18n-js": "^3.0.3",
|
||||
"@types/react-native-vector-icons": "^6.4.6",
|
||||
"@types/jest": "^25.2.3",
|
||||
"@types/react-native": "^0.63.2",
|
||||
"@types/react-native-calendars": "^1.20.10",
|
||||
"@types/react-native-vector-icons": "^6.4.6",
|
||||
"@types/react-test-renderer": "^16.9.2",
|
||||
"@typescript-eslint/eslint-plugin": "^2.27.0",
|
||||
"@typescript-eslint/parser": "^2.27.0",
|
||||
|
|
|
@ -17,15 +17,13 @@
|
|||
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// @flow
|
||||
|
||||
import * as React from 'react';
|
||||
import {StyleSheet, View} from 'react-native';
|
||||
import * as Animatable from 'react-native-animatable';
|
||||
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
|
||||
type PropsType = {
|
||||
icon: string,
|
||||
icon: string;
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
|
@ -37,24 +35,14 @@ const styles = StyleSheet.create({
|
|||
},
|
||||
});
|
||||
|
||||
class IntroIcon extends React.Component<PropsType> {
|
||||
shouldComponentUpdate(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
render(): React.Node {
|
||||
const {icon} = this.props;
|
||||
return (
|
||||
<View style={{flex: 1}}>
|
||||
<Animatable.View
|
||||
useNativeDriver
|
||||
style={styles.center}
|
||||
animation="fadeIn">
|
||||
<MaterialCommunityIcons name={icon} color="#fff" size={200} />
|
||||
</Animatable.View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
function IntroIcon(props: PropsType) {
|
||||
return (
|
||||
<View style={{flex: 1}}>
|
||||
<Animatable.View useNativeDriver style={styles.center} animation="fadeIn">
|
||||
<MaterialCommunityIcons name={props.icon} color="#fff" size={200} />
|
||||
</Animatable.View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
export default IntroIcon;
|
|
@ -17,8 +17,6 @@
|
|||
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// @flow
|
||||
|
||||
import * as React from 'react';
|
||||
import {StyleSheet, View} from 'react-native';
|
||||
import Mascot, {MASCOT_STYLE} from '../Mascot/Mascot';
|
||||
|
@ -32,34 +30,28 @@ const styles = StyleSheet.create({
|
|||
},
|
||||
});
|
||||
|
||||
class MascotIntroEnd extends React.Component<null> {
|
||||
shouldComponentUpdate(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
render(): React.Node {
|
||||
return (
|
||||
<View style={{flex: 1}}>
|
||||
<Mascot
|
||||
style={{
|
||||
...styles.center,
|
||||
width: '80%',
|
||||
}}
|
||||
emotion={MASCOT_STYLE.COOL}
|
||||
animated
|
||||
entryAnimation={{
|
||||
animation: 'slideInDown',
|
||||
duration: 2000,
|
||||
}}
|
||||
loopAnimation={{
|
||||
animation: 'pulse',
|
||||
duration: 2000,
|
||||
iterationCount: 'infinite',
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
function MascotIntroEnd() {
|
||||
return (
|
||||
<View style={{flex: 1}}>
|
||||
<Mascot
|
||||
style={{
|
||||
...styles.center,
|
||||
width: '80%',
|
||||
}}
|
||||
emotion={MASCOT_STYLE.COOL}
|
||||
animated
|
||||
entryAnimation={{
|
||||
animation: 'slideInDown',
|
||||
duration: 2000,
|
||||
}}
|
||||
loopAnimation={{
|
||||
animation: 'pulse',
|
||||
duration: 2000,
|
||||
iterationCount: 'infinite',
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
export default MascotIntroEnd;
|
|
@ -17,8 +17,6 @@
|
|||
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// @flow
|
||||
|
||||
import * as React from 'react';
|
||||
import {StyleSheet, View} from 'react-native';
|
||||
import * as Animatable from 'react-native-animatable';
|
||||
|
@ -34,62 +32,56 @@ const styles = StyleSheet.create({
|
|||
},
|
||||
});
|
||||
|
||||
class MascotIntroWelcome extends React.Component<null> {
|
||||
shouldComponentUpdate(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
render(): React.Node {
|
||||
return (
|
||||
<View style={{flex: 1}}>
|
||||
<Mascot
|
||||
function MascotIntroWelcome() {
|
||||
return (
|
||||
<View style={{flex: 1}}>
|
||||
<Mascot
|
||||
style={{
|
||||
...styles.center,
|
||||
width: '80%',
|
||||
}}
|
||||
emotion={MASCOT_STYLE.NORMAL}
|
||||
animated
|
||||
entryAnimation={{
|
||||
animation: 'bounceIn',
|
||||
duration: 2000,
|
||||
}}
|
||||
/>
|
||||
<Animatable.Text
|
||||
useNativeDriver
|
||||
animation="fadeInUp"
|
||||
duration={500}
|
||||
style={{
|
||||
color: '#fff',
|
||||
textAlign: 'center',
|
||||
fontSize: 25,
|
||||
}}>
|
||||
PABLO
|
||||
</Animatable.Text>
|
||||
<Animatable.View
|
||||
useNativeDriver
|
||||
animation="fadeInUp"
|
||||
duration={500}
|
||||
delay={200}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
bottom: 30,
|
||||
right: '20%',
|
||||
width: 50,
|
||||
height: 50,
|
||||
}}>
|
||||
<MaterialCommunityIcons
|
||||
style={{
|
||||
...styles.center,
|
||||
width: '80%',
|
||||
}}
|
||||
emotion={MASCOT_STYLE.NORMAL}
|
||||
animated
|
||||
entryAnimation={{
|
||||
animation: 'bounceIn',
|
||||
duration: 2000,
|
||||
transform: [{rotateZ: '70deg'}],
|
||||
}}
|
||||
name="undo"
|
||||
color="#fff"
|
||||
size={40}
|
||||
/>
|
||||
<Animatable.Text
|
||||
useNativeDriver
|
||||
animation="fadeInUp"
|
||||
duration={500}
|
||||
style={{
|
||||
color: '#fff',
|
||||
textAlign: 'center',
|
||||
fontSize: 25,
|
||||
}}>
|
||||
PABLO
|
||||
</Animatable.Text>
|
||||
<Animatable.View
|
||||
useNativeDriver
|
||||
animation="fadeInUp"
|
||||
duration={500}
|
||||
delay={200}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
bottom: 30,
|
||||
right: '20%',
|
||||
width: 50,
|
||||
height: 50,
|
||||
}}>
|
||||
<MaterialCommunityIcons
|
||||
style={{
|
||||
...styles.center,
|
||||
transform: [{rotateZ: '70deg'}],
|
||||
}}
|
||||
name="undo"
|
||||
color="#fff"
|
||||
size={40}
|
||||
/>
|
||||
</Animatable.View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
</Animatable.View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
export default MascotIntroWelcome;
|
|
@ -1,82 +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 {View} from 'react-native';
|
||||
import {withTheme} from 'react-native-paper';
|
||||
import {Agenda} from 'react-native-calendars';
|
||||
import type {CustomThemeType} from '../../managers/ThemeManager';
|
||||
|
||||
type PropsType = {
|
||||
theme: CustomThemeType,
|
||||
onRef: (ref: Agenda) => void,
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstraction layer for Agenda component, using custom configuration
|
||||
*/
|
||||
class CustomAgenda extends React.Component<PropsType> {
|
||||
getAgenda(): React.Node {
|
||||
const {props} = this;
|
||||
return (
|
||||
<Agenda
|
||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||
{...props}
|
||||
ref={props.onRef}
|
||||
theme={{
|
||||
backgroundColor: props.theme.colors.agendaBackgroundColor,
|
||||
calendarBackground: props.theme.colors.background,
|
||||
textSectionTitleColor: props.theme.colors.agendaDayTextColor,
|
||||
selectedDayBackgroundColor: props.theme.colors.primary,
|
||||
selectedDayTextColor: '#ffffff',
|
||||
todayTextColor: props.theme.colors.primary,
|
||||
dayTextColor: props.theme.colors.text,
|
||||
textDisabledColor: props.theme.colors.agendaDayTextColor,
|
||||
dotColor: props.theme.colors.primary,
|
||||
selectedDotColor: '#ffffff',
|
||||
arrowColor: 'orange',
|
||||
monthTextColor: props.theme.colors.primary,
|
||||
indicatorColor: props.theme.colors.primary,
|
||||
textDayFontWeight: '300',
|
||||
textMonthFontWeight: 'bold',
|
||||
textDayHeaderFontWeight: '300',
|
||||
textDayFontSize: 16,
|
||||
textMonthFontSize: 16,
|
||||
textDayHeaderFontSize: 16,
|
||||
agendaDayTextColor: props.theme.colors.agendaDayTextColor,
|
||||
agendaDayNumColor: props.theme.colors.agendaDayTextColor,
|
||||
agendaTodayColor: props.theme.colors.primary,
|
||||
agendaKnobColor: props.theme.colors.primary,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
render(): React.Node {
|
||||
const {props} = this;
|
||||
// Completely recreate the component on theme change to force theme reload
|
||||
if (props.theme.dark)
|
||||
return <View style={{flex: 1}}>{this.getAgenda()}</View>;
|
||||
return this.getAgenda();
|
||||
}
|
||||
}
|
||||
|
||||
export default withTheme(CustomAgenda);
|
75
src/components/Overrides/CustomAgenda.tsx
Normal file
75
src/components/Overrides/CustomAgenda.tsx
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* 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 {View} from 'react-native';
|
||||
import {useTheme} from 'react-native-paper';
|
||||
import {Agenda, AgendaProps} from 'react-native-calendars';
|
||||
|
||||
type PropsType = {
|
||||
onRef: (ref: Agenda<any>) => void;
|
||||
} & AgendaProps<any>;
|
||||
|
||||
/**
|
||||
* Abstraction layer for Agenda component, using custom configuration
|
||||
*/
|
||||
function CustomAgenda(props: PropsType) {
|
||||
const theme = useTheme();
|
||||
function getAgenda() {
|
||||
return (
|
||||
<Agenda
|
||||
{...props}
|
||||
ref={props.onRef}
|
||||
theme={{
|
||||
backgroundColor: theme.colors.agendaBackgroundColor,
|
||||
calendarBackground: theme.colors.background,
|
||||
textSectionTitleColor: theme.colors.agendaDayTextColor,
|
||||
selectedDayBackgroundColor: theme.colors.primary,
|
||||
selectedDayTextColor: '#ffffff',
|
||||
todayTextColor: theme.colors.primary,
|
||||
dayTextColor: theme.colors.text,
|
||||
textDisabledColor: theme.colors.agendaDayTextColor,
|
||||
dotColor: theme.colors.primary,
|
||||
selectedDotColor: '#ffffff',
|
||||
arrowColor: 'orange',
|
||||
monthTextColor: theme.colors.primary,
|
||||
indicatorColor: theme.colors.primary,
|
||||
textDayFontWeight: '300',
|
||||
textMonthFontWeight: 'bold',
|
||||
textDayHeaderFontWeight: '300',
|
||||
textDayFontSize: 16,
|
||||
textMonthFontSize: 16,
|
||||
textDayHeaderFontSize: 16,
|
||||
agendaDayTextColor: theme.colors.agendaDayTextColor,
|
||||
agendaDayNumColor: theme.colors.agendaDayTextColor,
|
||||
agendaTodayColor: theme.colors.primary,
|
||||
agendaKnobColor: theme.colors.primary,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// Completely recreate the component on theme change to force theme reload
|
||||
if (theme.dark) {
|
||||
return <View style={{flex: 1}}>{getAgenda()}</View>;
|
||||
}
|
||||
return getAgenda();
|
||||
}
|
||||
|
||||
export default CustomAgenda;
|
|
@ -1,77 +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/>.
|
||||
*/
|
||||
|
||||
/* eslint-disable flowtype/require-parameter-type */
|
||||
// @flow
|
||||
|
||||
import * as React from 'react';
|
||||
import {Text, withTheme} from 'react-native-paper';
|
||||
import HTML from 'react-native-render-html';
|
||||
import {Linking} from 'react-native';
|
||||
import type {CustomThemeType} from '../../managers/ThemeManager';
|
||||
|
||||
type PropsType = {
|
||||
theme: CustomThemeType,
|
||||
html: string,
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstraction layer for Agenda component, using custom configuration
|
||||
*/
|
||||
class CustomHTML extends React.Component<PropsType> {
|
||||
openWebLink = (event: {...}, link: string) => {
|
||||
Linking.openURL(link);
|
||||
};
|
||||
|
||||
getBasicText = (
|
||||
htmlAttribs,
|
||||
children,
|
||||
convertedCSSStyles,
|
||||
passProps,
|
||||
): React.Node => {
|
||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||
return <Text {...passProps}>{children}</Text>;
|
||||
};
|
||||
|
||||
getListBullet = (): React.Node => {
|
||||
return <Text>- </Text>;
|
||||
};
|
||||
|
||||
render(): React.Node {
|
||||
const {props} = this;
|
||||
// Surround description with p to allow text styling if the description is not html
|
||||
return (
|
||||
<HTML
|
||||
html={`<p>${props.html}</p>`}
|
||||
renderers={{
|
||||
p: this.getBasicText,
|
||||
li: this.getBasicText,
|
||||
}}
|
||||
listsPrefixesRenderers={{
|
||||
ul: this.getListBullet,
|
||||
}}
|
||||
ignoredTags={['img']}
|
||||
ignoredStyles={['color', 'background-color']}
|
||||
onLinkPress={this.openWebLink}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withTheme(CustomHTML);
|
68
src/components/Overrides/CustomHTML.tsx
Normal file
68
src/components/Overrides/CustomHTML.tsx
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* 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 {Text} from 'react-native-paper';
|
||||
import HTML from 'react-native-render-html';
|
||||
import {GestureResponderEvent, Linking} from 'react-native';
|
||||
|
||||
type PropsType = {
|
||||
html: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstraction layer for Agenda component, using custom configuration
|
||||
*/
|
||||
function CustomHTML(props: PropsType) {
|
||||
const openWebLink = (event: GestureResponderEvent, link: string) => {
|
||||
Linking.openURL(link);
|
||||
};
|
||||
|
||||
const getBasicText = (
|
||||
htmlAttribs: any,
|
||||
children: any,
|
||||
convertedCSSStyles: any,
|
||||
passProps: any,
|
||||
) => {
|
||||
return <Text {...passProps}>{children}</Text>;
|
||||
};
|
||||
|
||||
const getListBullet = () => {
|
||||
return <Text>- </Text>;
|
||||
};
|
||||
|
||||
// Surround description with p to allow text styling if the description is not html
|
||||
return (
|
||||
<HTML
|
||||
html={`<p>${props.html}</p>`}
|
||||
renderers={{
|
||||
p: getBasicText,
|
||||
li: getBasicText,
|
||||
}}
|
||||
listsPrefixesRenderers={{
|
||||
ul: getListBullet,
|
||||
}}
|
||||
ignoredTags={['img']}
|
||||
ignoredStyles={['color', 'background-color']}
|
||||
onLinkPress={openWebLink}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default CustomHTML;
|
|
@ -17,39 +17,31 @@
|
|||
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// @flow
|
||||
|
||||
import * as React from 'react';
|
||||
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import {HeaderButton, HeaderButtons} from 'react-navigation-header-buttons';
|
||||
import {withTheme} from 'react-native-paper';
|
||||
import type {CustomThemeType} from '../../managers/ThemeManager';
|
||||
import {
|
||||
HeaderButton,
|
||||
HeaderButtonProps,
|
||||
HeaderButtons,
|
||||
HeaderButtonsProps,
|
||||
} from 'react-navigation-header-buttons';
|
||||
import {useTheme} from 'react-native-paper';
|
||||
|
||||
const MaterialHeaderButton = (props: {
|
||||
theme: CustomThemeType,
|
||||
color: string,
|
||||
}): React.Node => {
|
||||
const {color, theme} = props;
|
||||
const MaterialHeaderButton = (props: HeaderButtonProps) => {
|
||||
const theme = useTheme();
|
||||
return (
|
||||
// $FlowFixMe
|
||||
<HeaderButton
|
||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||
{...props}
|
||||
IconComponent={MaterialCommunityIcons}
|
||||
iconSize={26}
|
||||
color={color != null ? color : theme.colors.text}
|
||||
color={props.color ? props.color : theme.colors.text}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const MaterialHeaderButtons = (props: {...}): React.Node => {
|
||||
const MaterialHeaderButtons = (props: HeaderButtonsProps) => {
|
||||
return (
|
||||
// $FlowFixMe
|
||||
<HeaderButtons
|
||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||
{...props}
|
||||
HeaderButtonComponent={withTheme(MaterialHeaderButton)}
|
||||
/>
|
||||
<HeaderButtons {...props} HeaderButtonComponent={MaterialHeaderButton} />
|
||||
);
|
||||
};
|
||||
|
|
@ -17,10 +17,14 @@
|
|||
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// @flow
|
||||
|
||||
import * as React from 'react';
|
||||
import {Platform, StatusBar, StyleSheet, View} from 'react-native';
|
||||
import {
|
||||
ListRenderItemInfo,
|
||||
Platform,
|
||||
StatusBar,
|
||||
StyleSheet,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import i18n from 'i18n-js';
|
||||
import AppIntroSlider from 'react-native-app-intro-slider';
|
||||
|
@ -35,26 +39,27 @@ import IntroIcon from '../Intro/IconIntro';
|
|||
import MascotIntroEnd from '../Intro/MascotIntroEnd';
|
||||
|
||||
type PropsType = {
|
||||
onDone: () => void,
|
||||
isUpdate: boolean,
|
||||
isAprilFools: boolean,
|
||||
onDone: () => void;
|
||||
isUpdate: boolean;
|
||||
isAprilFools: boolean;
|
||||
};
|
||||
|
||||
type StateType = {
|
||||
currentSlide: number,
|
||||
currentSlide: number;
|
||||
};
|
||||
|
||||
export type IntroSlideType = {
|
||||
key: string,
|
||||
title: string,
|
||||
text: string,
|
||||
view: () => React.Node,
|
||||
mascotStyle?: number,
|
||||
colors: [string, string],
|
||||
key: string;
|
||||
title: string;
|
||||
text: string;
|
||||
view: () => React.ReactNode;
|
||||
mascotStyle?: number;
|
||||
colors: [string, string];
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
mainContent: {
|
||||
flex: 1,
|
||||
paddingBottom: 100,
|
||||
},
|
||||
text: {
|
||||
|
@ -83,7 +88,7 @@ const styles = StyleSheet.create({
|
|||
*/
|
||||
export default class CustomIntroSlider extends React.Component<
|
||||
PropsType,
|
||||
StateType,
|
||||
StateType
|
||||
> {
|
||||
sliderRef: {current: null | AppIntroSlider};
|
||||
|
||||
|
@ -98,8 +103,9 @@ export default class CustomIntroSlider extends React.Component<
|
|||
/**
|
||||
* Generates intro slides
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
constructor(props: PropsType) {
|
||||
super(props);
|
||||
this.currentSlides = [];
|
||||
this.state = {
|
||||
currentSlide: 0,
|
||||
};
|
||||
|
@ -109,14 +115,14 @@ export default class CustomIntroSlider extends React.Component<
|
|||
key: '0', // Mascot
|
||||
title: i18n.t('intro.slideMain.title'),
|
||||
text: i18n.t('intro.slideMain.text'),
|
||||
view: (): React.Node => <MascotIntroWelcome />,
|
||||
view: () => <MascotIntroWelcome />,
|
||||
colors: ['#be1522', '#57080e'],
|
||||
},
|
||||
{
|
||||
key: '1',
|
||||
title: i18n.t('intro.slidePlanex.title'),
|
||||
text: i18n.t('intro.slidePlanex.text'),
|
||||
view: (): React.Node => <IntroIcon icon="calendar-clock" />,
|
||||
view: () => <IntroIcon icon="calendar-clock" />,
|
||||
mascotStyle: MASCOT_STYLE.INTELLO,
|
||||
colors: ['#be1522', '#57080e'],
|
||||
},
|
||||
|
@ -124,7 +130,7 @@ export default class CustomIntroSlider extends React.Component<
|
|||
key: '2',
|
||||
title: i18n.t('intro.slideEvents.title'),
|
||||
text: i18n.t('intro.slideEvents.text'),
|
||||
view: (): React.Node => <IntroIcon icon="calendar-star" />,
|
||||
view: () => <IntroIcon icon="calendar-star" />,
|
||||
mascotStyle: MASCOT_STYLE.HAPPY,
|
||||
colors: ['#be1522', '#57080e'],
|
||||
},
|
||||
|
@ -132,7 +138,7 @@ export default class CustomIntroSlider extends React.Component<
|
|||
key: '3',
|
||||
title: i18n.t('intro.slideServices.title'),
|
||||
text: i18n.t('intro.slideServices.text'),
|
||||
view: (): React.Node => <IntroIcon icon="view-dashboard-variant" />,
|
||||
view: () => <IntroIcon icon="view-dashboard-variant" />,
|
||||
mascotStyle: MASCOT_STYLE.CUTE,
|
||||
colors: ['#be1522', '#57080e'],
|
||||
},
|
||||
|
@ -140,7 +146,7 @@ export default class CustomIntroSlider extends React.Component<
|
|||
key: '4',
|
||||
title: i18n.t('intro.slideDone.title'),
|
||||
text: i18n.t('intro.slideDone.text'),
|
||||
view: (): React.Node => <MascotIntroEnd />,
|
||||
view: () => <MascotIntroEnd />,
|
||||
colors: ['#9c165b', '#3e042b'],
|
||||
},
|
||||
];
|
||||
|
@ -152,7 +158,7 @@ export default class CustomIntroSlider extends React.Component<
|
|||
key: '1',
|
||||
title: i18n.t('intro.aprilFoolsSlide.title'),
|
||||
text: i18n.t('intro.aprilFoolsSlide.text'),
|
||||
view: (): React.Node => <View />,
|
||||
view: () => <View />,
|
||||
mascotStyle: MASCOT_STYLE.NORMAL,
|
||||
colors: ['#e01928', '#be1522'],
|
||||
},
|
||||
|
@ -162,21 +168,21 @@ export default class CustomIntroSlider extends React.Component<
|
|||
/**
|
||||
* Render item to be used for the intro introSlides
|
||||
*
|
||||
* @param item The item to be displayed
|
||||
* @param dimensions Dimensions of the item
|
||||
* @param data
|
||||
*/
|
||||
getIntroRenderItem = ({
|
||||
item,
|
||||
dimensions,
|
||||
}: {
|
||||
item: IntroSlideType,
|
||||
dimensions: {width: number, height: number},
|
||||
}): React.Node => {
|
||||
getIntroRenderItem = (
|
||||
data:
|
||||
| (ListRenderItemInfo<IntroSlideType> & {
|
||||
dimensions: {width: number; height: number};
|
||||
})
|
||||
| ListRenderItemInfo<IntroSlideType>,
|
||||
) => {
|
||||
const item = data.item;
|
||||
const {state} = this;
|
||||
const index = parseInt(item.key, 10);
|
||||
return (
|
||||
<LinearGradient
|
||||
style={[styles.mainContent, dimensions]}
|
||||
style={[styles.mainContent]}
|
||||
colors={item.colors}
|
||||
start={{x: 0, y: 0.1}}
|
||||
end={{x: 0.1, y: 1}}>
|
||||
|
@ -254,7 +260,9 @@ export default class CustomIntroSlider extends React.Component<
|
|||
};
|
||||
|
||||
static setStatusBarColor(color: string) {
|
||||
if (Platform.OS === 'android') StatusBar.setBackgroundColor(color, true);
|
||||
if (Platform.OS === 'android') {
|
||||
StatusBar.setBackgroundColor(color, true);
|
||||
}
|
||||
}
|
||||
|
||||
onSlideChange = (index: number) => {
|
||||
|
@ -266,8 +274,9 @@ export default class CustomIntroSlider extends React.Component<
|
|||
CustomIntroSlider.setStatusBarColor(
|
||||
this.currentSlides[this.currentSlides.length - 1].colors[0],
|
||||
);
|
||||
if (this.sliderRef.current != null)
|
||||
if (this.sliderRef.current != null) {
|
||||
this.sliderRef.current.goToSlide(this.currentSlides.length - 1);
|
||||
}
|
||||
};
|
||||
|
||||
onDone = () => {
|
||||
|
@ -278,7 +287,7 @@ export default class CustomIntroSlider extends React.Component<
|
|||
props.onDone();
|
||||
};
|
||||
|
||||
getRenderNextButton = (): React.Node => {
|
||||
getRenderNextButton = () => {
|
||||
return (
|
||||
<Animatable.View
|
||||
useNativeDriver
|
||||
|
@ -293,7 +302,7 @@ export default class CustomIntroSlider extends React.Component<
|
|||
);
|
||||
};
|
||||
|
||||
getRenderDoneButton = (): React.Node => {
|
||||
getRenderDoneButton = () => {
|
||||
return (
|
||||
<Animatable.View
|
||||
useNativeDriver
|
||||
|
@ -308,11 +317,14 @@ export default class CustomIntroSlider extends React.Component<
|
|||
);
|
||||
};
|
||||
|
||||
render(): React.Node {
|
||||
render() {
|
||||
const {props, state} = this;
|
||||
this.currentSlides = this.introSlides;
|
||||
if (props.isUpdate) this.currentSlides = this.updateSlides;
|
||||
else if (props.isAprilFools) this.currentSlides = this.aprilFoolsSlides;
|
||||
if (props.isUpdate) {
|
||||
this.currentSlides = this.updateSlides;
|
||||
} else if (props.isAprilFools) {
|
||||
this.currentSlides = this.aprilFoolsSlides;
|
||||
}
|
||||
CustomIntroSlider.setStatusBarColor(this.currentSlides[0].colors[0]);
|
||||
return (
|
||||
<AppIntroSlider
|
|
@ -17,14 +17,11 @@
|
|||
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// @flow
|
||||
|
||||
import * as React from 'react';
|
||||
import {withTheme} from 'react-native-paper';
|
||||
import {useTheme} from 'react-native-paper';
|
||||
import {Modalize} from 'react-native-modalize';
|
||||
import {View} from 'react-native-animatable';
|
||||
import CustomTabBar from '../Tabbar/CustomTabBar';
|
||||
import type {CustomThemeType} from '../../managers/ThemeManager';
|
||||
|
||||
/**
|
||||
* Abstraction layer for Modalize component, using custom configuration
|
||||
|
@ -33,11 +30,11 @@ import type {CustomThemeType} from '../../managers/ThemeManager';
|
|||
* @return {*}
|
||||
*/
|
||||
function CustomModal(props: {
|
||||
theme: CustomThemeType,
|
||||
onRef: (re: Modalize) => void,
|
||||
children?: React.Node,
|
||||
}): React.Node {
|
||||
const {theme, onRef, children} = props;
|
||||
onRef: (re: Modalize) => void;
|
||||
children?: React.ReactNode;
|
||||
}) {
|
||||
const theme = useTheme();
|
||||
const {onRef, children} = props;
|
||||
return (
|
||||
<Modalize
|
||||
ref={onRef}
|
||||
|
@ -55,6 +52,4 @@ function CustomModal(props: {
|
|||
);
|
||||
}
|
||||
|
||||
CustomModal.defaultProps = {children: null};
|
||||
|
||||
export default withTheme(CustomModal);
|
||||
export default CustomModal;
|
|
@ -1,84 +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 {Text, withTheme} from 'react-native-paper';
|
||||
import {View} from 'react-native-animatable';
|
||||
import Slider, {SliderProps} from '@react-native-community/slider';
|
||||
import type {CustomThemeType} from '../../managers/ThemeManager';
|
||||
|
||||
type PropsType = {
|
||||
theme: CustomThemeType,
|
||||
valueSuffix?: string,
|
||||
...SliderProps,
|
||||
};
|
||||
|
||||
type StateType = {
|
||||
currentValue: number,
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstraction layer for Modalize component, using custom configuration
|
||||
*
|
||||
* @param props Props to pass to the element. Must specify an onRef prop to get an Modalize ref.
|
||||
* @return {*}
|
||||
*/
|
||||
class CustomSlider extends React.Component<PropsType, StateType> {
|
||||
static defaultProps = {
|
||||
valueSuffix: '',
|
||||
};
|
||||
|
||||
constructor(props: PropsType) {
|
||||
super(props);
|
||||
this.state = {
|
||||
currentValue: props.value,
|
||||
};
|
||||
}
|
||||
|
||||
onValueChange = (value: number) => {
|
||||
const {props} = this;
|
||||
this.setState({currentValue: value});
|
||||
if (props.onValueChange != null) props.onValueChange(value);
|
||||
};
|
||||
|
||||
render(): React.Node {
|
||||
const {props, state} = this;
|
||||
return (
|
||||
<View style={{flex: 1, flexDirection: 'row'}}>
|
||||
<Text
|
||||
style={{
|
||||
marginHorizontal: 10,
|
||||
marginTop: 'auto',
|
||||
marginBottom: 'auto',
|
||||
}}>
|
||||
{state.currentValue}min
|
||||
</Text>
|
||||
<Slider
|
||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||
{...props}
|
||||
onValueChange={this.onValueChange}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withTheme(CustomSlider);
|
61
src/components/Overrides/CustomSlider.tsx
Normal file
61
src/components/Overrides/CustomSlider.tsx
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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 {Text} from 'react-native-paper';
|
||||
import {View} from 'react-native-animatable';
|
||||
import Slider, {SliderProps} from '@react-native-community/slider';
|
||||
import {useState} from 'react';
|
||||
|
||||
type PropsType = {
|
||||
valueSuffix?: string;
|
||||
} & SliderProps;
|
||||
|
||||
/**
|
||||
* Abstraction layer for Modalize component, using custom configuration
|
||||
*
|
||||
* @param props Props to pass to the element. Must specify an onRef prop to get an Modalize ref.
|
||||
* @return {*}
|
||||
*/
|
||||
function CustomSlider(props: PropsType) {
|
||||
const [currentValue, setCurrentValue] = useState(props.value);
|
||||
|
||||
const onValueChange = (value: number) => {
|
||||
setCurrentValue(value);
|
||||
if (props.onValueChange) {
|
||||
props.onValueChange(value);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={{flex: 1, flexDirection: 'row'}}>
|
||||
<Text
|
||||
style={{
|
||||
marginHorizontal: 10,
|
||||
marginTop: 'auto',
|
||||
marginBottom: 'auto',
|
||||
}}>
|
||||
{currentValue}min
|
||||
</Text>
|
||||
<Slider {...props} ref={undefined} onValueChange={onValueChange} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
export default CustomSlider;
|
Loading…
Reference in a new issue