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": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@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": {
|
"@types/react-native-vector-icons": {
|
||||||
"version": "6.4.6",
|
"version": "6.4.6",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-native-vector-icons/-/react-native-vector-icons-6.4.6.tgz",
|
"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",
|
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz",
|
||||||
"integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw=="
|
"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": {
|
"@types/yargs": {
|
||||||
"version": "15.0.5",
|
"version": "15.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz",
|
||||||
|
|
|
@ -67,9 +67,10 @@
|
||||||
"@babel/runtime": "^7.11.0",
|
"@babel/runtime": "^7.11.0",
|
||||||
"@react-native-community/eslint-config": "^1.1.0",
|
"@react-native-community/eslint-config": "^1.1.0",
|
||||||
"@types/i18n-js": "^3.0.3",
|
"@types/i18n-js": "^3.0.3",
|
||||||
"@types/react-native-vector-icons": "^6.4.6",
|
|
||||||
"@types/jest": "^25.2.3",
|
"@types/jest": "^25.2.3",
|
||||||
"@types/react-native": "^0.63.2",
|
"@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",
|
"@types/react-test-renderer": "^16.9.2",
|
||||||
"@typescript-eslint/eslint-plugin": "^2.27.0",
|
"@typescript-eslint/eslint-plugin": "^2.27.0",
|
||||||
"@typescript-eslint/parser": "^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/>.
|
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// @flow
|
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {StyleSheet, View} from 'react-native';
|
import {StyleSheet, View} from 'react-native';
|
||||||
import * as Animatable from 'react-native-animatable';
|
import * as Animatable from 'react-native-animatable';
|
||||||
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
|
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||||
|
|
||||||
type PropsType = {
|
type PropsType = {
|
||||||
icon: string,
|
icon: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
|
@ -37,24 +35,14 @@ const styles = StyleSheet.create({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
class IntroIcon extends React.Component<PropsType> {
|
function IntroIcon(props: PropsType) {
|
||||||
shouldComponentUpdate(): boolean {
|
return (
|
||||||
return false;
|
<View style={{flex: 1}}>
|
||||||
}
|
<Animatable.View useNativeDriver style={styles.center} animation="fadeIn">
|
||||||
|
<MaterialCommunityIcons name={props.icon} color="#fff" size={200} />
|
||||||
render(): React.Node {
|
</Animatable.View>
|
||||||
const {icon} = this.props;
|
</View>
|
||||||
return (
|
);
|
||||||
<View style={{flex: 1}}>
|
|
||||||
<Animatable.View
|
|
||||||
useNativeDriver
|
|
||||||
style={styles.center}
|
|
||||||
animation="fadeIn">
|
|
||||||
<MaterialCommunityIcons name={icon} color="#fff" size={200} />
|
|
||||||
</Animatable.View>
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default IntroIcon;
|
export default IntroIcon;
|
|
@ -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 {StyleSheet, View} from 'react-native';
|
import {StyleSheet, View} from 'react-native';
|
||||||
import Mascot, {MASCOT_STYLE} from '../Mascot/Mascot';
|
import Mascot, {MASCOT_STYLE} from '../Mascot/Mascot';
|
||||||
|
@ -32,34 +30,28 @@ const styles = StyleSheet.create({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
class MascotIntroEnd extends React.Component<null> {
|
function MascotIntroEnd() {
|
||||||
shouldComponentUpdate(): boolean {
|
return (
|
||||||
return false;
|
<View style={{flex: 1}}>
|
||||||
}
|
<Mascot
|
||||||
|
style={{
|
||||||
render(): React.Node {
|
...styles.center,
|
||||||
return (
|
width: '80%',
|
||||||
<View style={{flex: 1}}>
|
}}
|
||||||
<Mascot
|
emotion={MASCOT_STYLE.COOL}
|
||||||
style={{
|
animated
|
||||||
...styles.center,
|
entryAnimation={{
|
||||||
width: '80%',
|
animation: 'slideInDown',
|
||||||
}}
|
duration: 2000,
|
||||||
emotion={MASCOT_STYLE.COOL}
|
}}
|
||||||
animated
|
loopAnimation={{
|
||||||
entryAnimation={{
|
animation: 'pulse',
|
||||||
animation: 'slideInDown',
|
duration: 2000,
|
||||||
duration: 2000,
|
iterationCount: 'infinite',
|
||||||
}}
|
}}
|
||||||
loopAnimation={{
|
/>
|
||||||
animation: 'pulse',
|
</View>
|
||||||
duration: 2000,
|
);
|
||||||
iterationCount: 'infinite',
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default MascotIntroEnd;
|
export default MascotIntroEnd;
|
|
@ -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 {StyleSheet, View} from 'react-native';
|
import {StyleSheet, View} from 'react-native';
|
||||||
import * as Animatable from 'react-native-animatable';
|
import * as Animatable from 'react-native-animatable';
|
||||||
|
@ -34,62 +32,56 @@ const styles = StyleSheet.create({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
class MascotIntroWelcome extends React.Component<null> {
|
function MascotIntroWelcome() {
|
||||||
shouldComponentUpdate(): boolean {
|
return (
|
||||||
return false;
|
<View style={{flex: 1}}>
|
||||||
}
|
<Mascot
|
||||||
|
style={{
|
||||||
render(): React.Node {
|
...styles.center,
|
||||||
return (
|
width: '80%',
|
||||||
<View style={{flex: 1}}>
|
}}
|
||||||
<Mascot
|
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={{
|
style={{
|
||||||
...styles.center,
|
...styles.center,
|
||||||
width: '80%',
|
transform: [{rotateZ: '70deg'}],
|
||||||
}}
|
|
||||||
emotion={MASCOT_STYLE.NORMAL}
|
|
||||||
animated
|
|
||||||
entryAnimation={{
|
|
||||||
animation: 'bounceIn',
|
|
||||||
duration: 2000,
|
|
||||||
}}
|
}}
|
||||||
|
name="undo"
|
||||||
|
color="#fff"
|
||||||
|
size={40}
|
||||||
/>
|
/>
|
||||||
<Animatable.Text
|
</Animatable.View>
|
||||||
useNativeDriver
|
</View>
|
||||||
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>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default MascotIntroWelcome;
|
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/>.
|
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// @flow
|
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
|
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||||
import {HeaderButton, HeaderButtons} from 'react-navigation-header-buttons';
|
import {
|
||||||
import {withTheme} from 'react-native-paper';
|
HeaderButton,
|
||||||
import type {CustomThemeType} from '../../managers/ThemeManager';
|
HeaderButtonProps,
|
||||||
|
HeaderButtons,
|
||||||
|
HeaderButtonsProps,
|
||||||
|
} from 'react-navigation-header-buttons';
|
||||||
|
import {useTheme} from 'react-native-paper';
|
||||||
|
|
||||||
const MaterialHeaderButton = (props: {
|
const MaterialHeaderButton = (props: HeaderButtonProps) => {
|
||||||
theme: CustomThemeType,
|
const theme = useTheme();
|
||||||
color: string,
|
|
||||||
}): React.Node => {
|
|
||||||
const {color, theme} = props;
|
|
||||||
return (
|
return (
|
||||||
// $FlowFixMe
|
|
||||||
<HeaderButton
|
<HeaderButton
|
||||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
|
||||||
{...props}
|
{...props}
|
||||||
IconComponent={MaterialCommunityIcons}
|
IconComponent={MaterialCommunityIcons}
|
||||||
iconSize={26}
|
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 (
|
return (
|
||||||
// $FlowFixMe
|
<HeaderButtons {...props} HeaderButtonComponent={MaterialHeaderButton} />
|
||||||
<HeaderButtons
|
|
||||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
|
||||||
{...props}
|
|
||||||
HeaderButtonComponent={withTheme(MaterialHeaderButton)}
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,10 +17,14 @@
|
||||||
* 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 {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 MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||||
import i18n from 'i18n-js';
|
import i18n from 'i18n-js';
|
||||||
import AppIntroSlider from 'react-native-app-intro-slider';
|
import AppIntroSlider from 'react-native-app-intro-slider';
|
||||||
|
@ -35,26 +39,27 @@ import IntroIcon from '../Intro/IconIntro';
|
||||||
import MascotIntroEnd from '../Intro/MascotIntroEnd';
|
import MascotIntroEnd from '../Intro/MascotIntroEnd';
|
||||||
|
|
||||||
type PropsType = {
|
type PropsType = {
|
||||||
onDone: () => void,
|
onDone: () => void;
|
||||||
isUpdate: boolean,
|
isUpdate: boolean;
|
||||||
isAprilFools: boolean,
|
isAprilFools: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type StateType = {
|
type StateType = {
|
||||||
currentSlide: number,
|
currentSlide: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type IntroSlideType = {
|
export type IntroSlideType = {
|
||||||
key: string,
|
key: string;
|
||||||
title: string,
|
title: string;
|
||||||
text: string,
|
text: string;
|
||||||
view: () => React.Node,
|
view: () => React.ReactNode;
|
||||||
mascotStyle?: number,
|
mascotStyle?: number;
|
||||||
colors: [string, string],
|
colors: [string, string];
|
||||||
};
|
};
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
mainContent: {
|
mainContent: {
|
||||||
|
flex: 1,
|
||||||
paddingBottom: 100,
|
paddingBottom: 100,
|
||||||
},
|
},
|
||||||
text: {
|
text: {
|
||||||
|
@ -83,7 +88,7 @@ const styles = StyleSheet.create({
|
||||||
*/
|
*/
|
||||||
export default class CustomIntroSlider extends React.Component<
|
export default class CustomIntroSlider extends React.Component<
|
||||||
PropsType,
|
PropsType,
|
||||||
StateType,
|
StateType
|
||||||
> {
|
> {
|
||||||
sliderRef: {current: null | AppIntroSlider};
|
sliderRef: {current: null | AppIntroSlider};
|
||||||
|
|
||||||
|
@ -98,8 +103,9 @@ export default class CustomIntroSlider extends React.Component<
|
||||||
/**
|
/**
|
||||||
* Generates intro slides
|
* Generates intro slides
|
||||||
*/
|
*/
|
||||||
constructor() {
|
constructor(props: PropsType) {
|
||||||
super();
|
super(props);
|
||||||
|
this.currentSlides = [];
|
||||||
this.state = {
|
this.state = {
|
||||||
currentSlide: 0,
|
currentSlide: 0,
|
||||||
};
|
};
|
||||||
|
@ -109,14 +115,14 @@ export default class CustomIntroSlider extends React.Component<
|
||||||
key: '0', // Mascot
|
key: '0', // Mascot
|
||||||
title: i18n.t('intro.slideMain.title'),
|
title: i18n.t('intro.slideMain.title'),
|
||||||
text: i18n.t('intro.slideMain.text'),
|
text: i18n.t('intro.slideMain.text'),
|
||||||
view: (): React.Node => <MascotIntroWelcome />,
|
view: () => <MascotIntroWelcome />,
|
||||||
colors: ['#be1522', '#57080e'],
|
colors: ['#be1522', '#57080e'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: '1',
|
key: '1',
|
||||||
title: i18n.t('intro.slidePlanex.title'),
|
title: i18n.t('intro.slidePlanex.title'),
|
||||||
text: i18n.t('intro.slidePlanex.text'),
|
text: i18n.t('intro.slidePlanex.text'),
|
||||||
view: (): React.Node => <IntroIcon icon="calendar-clock" />,
|
view: () => <IntroIcon icon="calendar-clock" />,
|
||||||
mascotStyle: MASCOT_STYLE.INTELLO,
|
mascotStyle: MASCOT_STYLE.INTELLO,
|
||||||
colors: ['#be1522', '#57080e'],
|
colors: ['#be1522', '#57080e'],
|
||||||
},
|
},
|
||||||
|
@ -124,7 +130,7 @@ export default class CustomIntroSlider extends React.Component<
|
||||||
key: '2',
|
key: '2',
|
||||||
title: i18n.t('intro.slideEvents.title'),
|
title: i18n.t('intro.slideEvents.title'),
|
||||||
text: i18n.t('intro.slideEvents.text'),
|
text: i18n.t('intro.slideEvents.text'),
|
||||||
view: (): React.Node => <IntroIcon icon="calendar-star" />,
|
view: () => <IntroIcon icon="calendar-star" />,
|
||||||
mascotStyle: MASCOT_STYLE.HAPPY,
|
mascotStyle: MASCOT_STYLE.HAPPY,
|
||||||
colors: ['#be1522', '#57080e'],
|
colors: ['#be1522', '#57080e'],
|
||||||
},
|
},
|
||||||
|
@ -132,7 +138,7 @@ export default class CustomIntroSlider extends React.Component<
|
||||||
key: '3',
|
key: '3',
|
||||||
title: i18n.t('intro.slideServices.title'),
|
title: i18n.t('intro.slideServices.title'),
|
||||||
text: i18n.t('intro.slideServices.text'),
|
text: i18n.t('intro.slideServices.text'),
|
||||||
view: (): React.Node => <IntroIcon icon="view-dashboard-variant" />,
|
view: () => <IntroIcon icon="view-dashboard-variant" />,
|
||||||
mascotStyle: MASCOT_STYLE.CUTE,
|
mascotStyle: MASCOT_STYLE.CUTE,
|
||||||
colors: ['#be1522', '#57080e'],
|
colors: ['#be1522', '#57080e'],
|
||||||
},
|
},
|
||||||
|
@ -140,7 +146,7 @@ export default class CustomIntroSlider extends React.Component<
|
||||||
key: '4',
|
key: '4',
|
||||||
title: i18n.t('intro.slideDone.title'),
|
title: i18n.t('intro.slideDone.title'),
|
||||||
text: i18n.t('intro.slideDone.text'),
|
text: i18n.t('intro.slideDone.text'),
|
||||||
view: (): React.Node => <MascotIntroEnd />,
|
view: () => <MascotIntroEnd />,
|
||||||
colors: ['#9c165b', '#3e042b'],
|
colors: ['#9c165b', '#3e042b'],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -152,7 +158,7 @@ export default class CustomIntroSlider extends React.Component<
|
||||||
key: '1',
|
key: '1',
|
||||||
title: i18n.t('intro.aprilFoolsSlide.title'),
|
title: i18n.t('intro.aprilFoolsSlide.title'),
|
||||||
text: i18n.t('intro.aprilFoolsSlide.text'),
|
text: i18n.t('intro.aprilFoolsSlide.text'),
|
||||||
view: (): React.Node => <View />,
|
view: () => <View />,
|
||||||
mascotStyle: MASCOT_STYLE.NORMAL,
|
mascotStyle: MASCOT_STYLE.NORMAL,
|
||||||
colors: ['#e01928', '#be1522'],
|
colors: ['#e01928', '#be1522'],
|
||||||
},
|
},
|
||||||
|
@ -162,21 +168,21 @@ export default class CustomIntroSlider extends React.Component<
|
||||||
/**
|
/**
|
||||||
* Render item to be used for the intro introSlides
|
* Render item to be used for the intro introSlides
|
||||||
*
|
*
|
||||||
* @param item The item to be displayed
|
* @param data
|
||||||
* @param dimensions Dimensions of the item
|
|
||||||
*/
|
*/
|
||||||
getIntroRenderItem = ({
|
getIntroRenderItem = (
|
||||||
item,
|
data:
|
||||||
dimensions,
|
| (ListRenderItemInfo<IntroSlideType> & {
|
||||||
}: {
|
dimensions: {width: number; height: number};
|
||||||
item: IntroSlideType,
|
})
|
||||||
dimensions: {width: number, height: number},
|
| ListRenderItemInfo<IntroSlideType>,
|
||||||
}): React.Node => {
|
) => {
|
||||||
|
const item = data.item;
|
||||||
const {state} = this;
|
const {state} = this;
|
||||||
const index = parseInt(item.key, 10);
|
const index = parseInt(item.key, 10);
|
||||||
return (
|
return (
|
||||||
<LinearGradient
|
<LinearGradient
|
||||||
style={[styles.mainContent, dimensions]}
|
style={[styles.mainContent]}
|
||||||
colors={item.colors}
|
colors={item.colors}
|
||||||
start={{x: 0, y: 0.1}}
|
start={{x: 0, y: 0.1}}
|
||||||
end={{x: 0.1, y: 1}}>
|
end={{x: 0.1, y: 1}}>
|
||||||
|
@ -254,7 +260,9 @@ export default class CustomIntroSlider extends React.Component<
|
||||||
};
|
};
|
||||||
|
|
||||||
static setStatusBarColor(color: string) {
|
static setStatusBarColor(color: string) {
|
||||||
if (Platform.OS === 'android') StatusBar.setBackgroundColor(color, true);
|
if (Platform.OS === 'android') {
|
||||||
|
StatusBar.setBackgroundColor(color, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onSlideChange = (index: number) => {
|
onSlideChange = (index: number) => {
|
||||||
|
@ -266,8 +274,9 @@ export default class CustomIntroSlider extends React.Component<
|
||||||
CustomIntroSlider.setStatusBarColor(
|
CustomIntroSlider.setStatusBarColor(
|
||||||
this.currentSlides[this.currentSlides.length - 1].colors[0],
|
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);
|
this.sliderRef.current.goToSlide(this.currentSlides.length - 1);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onDone = () => {
|
onDone = () => {
|
||||||
|
@ -278,7 +287,7 @@ export default class CustomIntroSlider extends React.Component<
|
||||||
props.onDone();
|
props.onDone();
|
||||||
};
|
};
|
||||||
|
|
||||||
getRenderNextButton = (): React.Node => {
|
getRenderNextButton = () => {
|
||||||
return (
|
return (
|
||||||
<Animatable.View
|
<Animatable.View
|
||||||
useNativeDriver
|
useNativeDriver
|
||||||
|
@ -293,7 +302,7 @@ export default class CustomIntroSlider extends React.Component<
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
getRenderDoneButton = (): React.Node => {
|
getRenderDoneButton = () => {
|
||||||
return (
|
return (
|
||||||
<Animatable.View
|
<Animatable.View
|
||||||
useNativeDriver
|
useNativeDriver
|
||||||
|
@ -308,11 +317,14 @@ export default class CustomIntroSlider extends React.Component<
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
render(): React.Node {
|
render() {
|
||||||
const {props, state} = this;
|
const {props, state} = this;
|
||||||
this.currentSlides = this.introSlides;
|
this.currentSlides = this.introSlides;
|
||||||
if (props.isUpdate) this.currentSlides = this.updateSlides;
|
if (props.isUpdate) {
|
||||||
else if (props.isAprilFools) this.currentSlides = this.aprilFoolsSlides;
|
this.currentSlides = this.updateSlides;
|
||||||
|
} else if (props.isAprilFools) {
|
||||||
|
this.currentSlides = this.aprilFoolsSlides;
|
||||||
|
}
|
||||||
CustomIntroSlider.setStatusBarColor(this.currentSlides[0].colors[0]);
|
CustomIntroSlider.setStatusBarColor(this.currentSlides[0].colors[0]);
|
||||||
return (
|
return (
|
||||||
<AppIntroSlider
|
<AppIntroSlider
|
|
@ -17,14 +17,11 @@
|
||||||
* 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 {withTheme} from 'react-native-paper';
|
import {useTheme} from 'react-native-paper';
|
||||||
import {Modalize} from 'react-native-modalize';
|
import {Modalize} from 'react-native-modalize';
|
||||||
import {View} from 'react-native-animatable';
|
import {View} from 'react-native-animatable';
|
||||||
import CustomTabBar from '../Tabbar/CustomTabBar';
|
import CustomTabBar from '../Tabbar/CustomTabBar';
|
||||||
import type {CustomThemeType} from '../../managers/ThemeManager';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstraction layer for Modalize component, using custom configuration
|
* Abstraction layer for Modalize component, using custom configuration
|
||||||
|
@ -33,11 +30,11 @@ import type {CustomThemeType} from '../../managers/ThemeManager';
|
||||||
* @return {*}
|
* @return {*}
|
||||||
*/
|
*/
|
||||||
function CustomModal(props: {
|
function CustomModal(props: {
|
||||||
theme: CustomThemeType,
|
onRef: (re: Modalize) => void;
|
||||||
onRef: (re: Modalize) => void,
|
children?: React.ReactNode;
|
||||||
children?: React.Node,
|
}) {
|
||||||
}): React.Node {
|
const theme = useTheme();
|
||||||
const {theme, onRef, children} = props;
|
const {onRef, children} = props;
|
||||||
return (
|
return (
|
||||||
<Modalize
|
<Modalize
|
||||||
ref={onRef}
|
ref={onRef}
|
||||||
|
@ -55,6 +52,4 @@ function CustomModal(props: {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomModal.defaultProps = {children: null};
|
export default CustomModal;
|
||||||
|
|
||||||
export default withTheme(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