Compare commits
32 Commits
@ -0,0 +1,22 @@
|
|||||||
|
kind: pipeline
|
||||||
|
type: docker
|
||||||
|
name: default
|
||||||
|
steps:
|
||||||
|
- name: build
|
||||||
|
image: hub.codefirst.iut.uca.fr/camille.petitalot/drone-sonarplugin-reactnative:latest
|
||||||
|
commands:
|
||||||
|
- cd JokesApp
|
||||||
|
- npm install
|
||||||
|
|
||||||
|
- name : sonar
|
||||||
|
image : hub.codefirst.iut.uca.fr/camille.petitalot/drone-sonarplugin-reactnative:latest
|
||||||
|
environment:
|
||||||
|
sonar_host: https://codefirst.iut.uca.fr/sonar/
|
||||||
|
sonar_token:
|
||||||
|
from_secret: SECRET_SONAR_LOGIN
|
||||||
|
project_key: JokesAppSonar
|
||||||
|
commands:
|
||||||
|
- cd JokesApp
|
||||||
|
- npm install
|
||||||
|
- npm run test
|
||||||
|
- sonar-scanner -Dsonar.projectKey=$${project_key} -Dsonar.sources=. -Dsonar.host.url=$${sonar_host} -Dsonar.login=$${sonar_token} -Dsonar.javascript.lcov.reportPaths=/lcov.info -Dsonar.exclusions=/coverage//*,/tests/*/
|
@ -0,0 +1,5 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/Tp_ReactNative.iml" filepath="$PROJECT_DIR$/.idea/Tp_ReactNative.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -1,5 +1,75 @@
|
|||||||
|
import {DarkTheme, Theme, useTheme} from "@react-navigation/native";
|
||||||
|
import React, {useEffect, useState} from "react";
|
||||||
|
import DefaultTheme from "@react-navigation/native/src/theming/DefaultTheme";
|
||||||
|
import {useColorScheme} from "react-native";
|
||||||
|
|
||||||
export const indigo = "rgba(14, 14, 44, 1)";
|
export const indigo = "rgba(14, 14, 44, 1)";
|
||||||
export const purpleColor = "rgba(74, 74, 104, 1)";
|
export const purpleColor = "rgba(74, 74, 104, 1)";
|
||||||
export const darksalmonColor = "rgba(233, 150, 122, 1)";
|
export const darksalmonColor = "rgba(233, 150, 122, 1)";
|
||||||
export const greyColor = "rgba(140, 140, 161, 1)";
|
export const greyColor = "rgba(140, 140, 161, 1)";
|
||||||
export const whiteColor = "rgba(239, 239, 253, 1)";
|
export const whiteColor = "rgba(239, 239, 253, 1)";
|
||||||
|
|
||||||
|
export const blackColor = "rgba(0, 0, 0, 1)";
|
||||||
|
|
||||||
|
|
||||||
|
export default function usePersonalTheme() {
|
||||||
|
|
||||||
|
|
||||||
|
useTheme()
|
||||||
|
const theme = React.useContext(ThemeContext);
|
||||||
|
const [isDark, setIsDark] = useState(false);
|
||||||
|
|
||||||
|
if (isDark) {
|
||||||
|
theme.dark = true;
|
||||||
|
theme.colors = MyDarkTheme.colors;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
theme.dark = false;
|
||||||
|
theme.colors = MyLightTheme.colors;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//const isDark = false;
|
||||||
|
|
||||||
|
|
||||||
|
const MyDarkTheme: Theme = {
|
||||||
|
dark: true,
|
||||||
|
colors: {
|
||||||
|
primary: indigo,
|
||||||
|
background: purpleColor,
|
||||||
|
card: darksalmonColor,
|
||||||
|
text: whiteColor,
|
||||||
|
border: whiteColor,
|
||||||
|
notification: whiteColor,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const MyLightTheme: Theme = {
|
||||||
|
dark: false,
|
||||||
|
colors: {
|
||||||
|
primary: whiteColor,
|
||||||
|
background: greyColor,
|
||||||
|
card: '',
|
||||||
|
text: blackColor,
|
||||||
|
border: blackColor,
|
||||||
|
notification: blackColor,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const ThemeContext = React.createContext<Theme>(MyDarkTheme);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
After Width: | Height: | Size: 8.2 KiB |
After Width: | Height: | Size: 7.7 KiB |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,103 @@
|
|||||||
|
import {useTheme} from "@react-navigation/native";
|
||||||
|
import {darksalmonColor, indigo, whiteColor} from "../Theme";
|
||||||
|
import React, {useEffect, useState} from "react";
|
||||||
|
import {getFavorite} from "../redux/store";
|
||||||
|
import {FlatList, SafeAreaView, StyleSheet, TouchableHighlight, View, Text} from "react-native";
|
||||||
|
import {JokeListItems} from "../components/ListeJokeComponent";
|
||||||
|
import {CustomJoke} from "../model/CustomJoke";
|
||||||
|
import {SampleJoke} from "../model/SampleJoke";
|
||||||
|
import {useAppSelector, useAppDispatch} from "../redux/store";
|
||||||
|
import {useDispatch} from "react-redux";
|
||||||
|
export function ListFavoriteJokeScreen({route, navigation}){
|
||||||
|
|
||||||
|
const favoriteJokes: CustomJoke[] = useAppSelector((state) => state.customReducer.favoriteJokes);
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const getFavoriteJokes = async () => {
|
||||||
|
// @ts-ignore
|
||||||
|
await dispatch(getFavorite());
|
||||||
|
}
|
||||||
|
getFavoriteJokes();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const styles = themeSettings();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SafeAreaView style={styles.container}>
|
||||||
|
{ favoriteJokes.length ? (
|
||||||
|
<FlatList
|
||||||
|
data = {favoriteJokes}
|
||||||
|
renderItem={({ item }) => (
|
||||||
|
<TouchableHighlight onPress={() => navigation.navigate("JokeDetail", {"joke" : item.id})}>
|
||||||
|
<JokeListItems item={item}/>
|
||||||
|
</TouchableHighlight>
|
||||||
|
)}
|
||||||
|
keyExtractor={(item) => item.id.toString()}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Text style={styles.title}>Aucun favoris</Text>
|
||||||
|
)}
|
||||||
|
|
||||||
|
</SafeAreaView>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export function themeSettings() {
|
||||||
|
const {colors} = useTheme();
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
title: {
|
||||||
|
fontSize: 24,
|
||||||
|
color: colors.text,
|
||||||
|
textAlign: 'center',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
marginVertical: 20,
|
||||||
|
},
|
||||||
|
titleResume: {
|
||||||
|
fontSize: 15,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: colors.background,
|
||||||
|
|
||||||
|
},
|
||||||
|
top: {
|
||||||
|
backgroundColor : indigo,
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
alignItems: "center",
|
||||||
|
margin: 9,
|
||||||
|
},
|
||||||
|
headerText: {
|
||||||
|
fontSize: 18,
|
||||||
|
color: whiteColor,
|
||||||
|
textAlign: 'center',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
},
|
||||||
|
img2: {
|
||||||
|
tintColor: whiteColor,
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
button2:{
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "center",
|
||||||
|
marginRight: 10,
|
||||||
|
borderRadius: 10,
|
||||||
|
alignItems: "center",
|
||||||
|
height: 30,
|
||||||
|
width: 70,
|
||||||
|
|
||||||
|
borderColor: darksalmonColor,
|
||||||
|
borderWidth: 1,
|
||||||
|
backgroundColor: darksalmonColor,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return styles;
|
||||||
|
}
|
@ -1,33 +1,125 @@
|
|||||||
import React from "react";
|
import React, {useContext, useEffect, useState} from "react";
|
||||||
|
|
||||||
|
import {
|
||||||
|
Appearance,
|
||||||
|
Button,
|
||||||
|
FlatList,
|
||||||
|
Image,
|
||||||
|
SafeAreaView,
|
||||||
|
ScrollView,
|
||||||
|
SectionListComponent,
|
||||||
|
StyleSheet, Switch, SwitchComponent,
|
||||||
|
Text, useColorScheme,
|
||||||
|
View
|
||||||
|
} from "react-native";
|
||||||
|
import usePersonalTheme, {
|
||||||
|
blackColor,
|
||||||
|
darksalmonColor,
|
||||||
|
greyColor,
|
||||||
|
indigo,
|
||||||
|
purpleColor,
|
||||||
|
whiteColor
|
||||||
|
} from "../Theme";
|
||||||
|
import {isEnabled} from "react-native/Libraries/Performance/Systrace";
|
||||||
|
import {DarkTheme, DefaultTheme, useTheme} from "@react-navigation/native";
|
||||||
|
import {storeTheme} from "../redux/store";
|
||||||
|
|
||||||
|
|
||||||
import {FlatList, Image, SafeAreaView, ScrollView, SectionListComponent, StyleSheet, Text, View} from "react-native";
|
|
||||||
import {indigo, purpleColor} from "../Theme";
|
|
||||||
|
|
||||||
export function SettingsScreen() {
|
export function SettingsScreen() {
|
||||||
|
|
||||||
|
const [isEnabled, setIsEnabled] = useState(false);
|
||||||
|
|
||||||
|
const toggleSwitch = () => {
|
||||||
|
setIsEnabled(previousState => {
|
||||||
|
const newIsEnabled = !previousState;
|
||||||
|
const newTheme = newIsEnabled ? DarkTheme : DefaultTheme;
|
||||||
|
console.log("newTheme", newTheme);
|
||||||
|
storeTheme(newTheme);
|
||||||
|
return newIsEnabled;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = themeSettings();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.font}>
|
<SafeAreaView style={styles.container}>
|
||||||
<Text style={styles.text}>Settings Page</Text>
|
<Text style={styles.title}>Réglages</Text>
|
||||||
<Text style={styles.text}>In Work</Text>
|
<View style={styles.settingsContainer}>
|
||||||
|
<View style={styles.settingRow}>
|
||||||
|
<View style={styles.settingRow}>
|
||||||
|
<Image style={styles.img} source={require('../assets/darkmode_icon.png')}/>
|
||||||
|
<Text style={styles.settingText}>Dark Mode</Text>
|
||||||
|
</View>
|
||||||
|
<Switch style={styles.switch}
|
||||||
|
trackColor={{ false: whiteColor, true: darksalmonColor }}
|
||||||
|
thumbColor={isEnabled ? whiteColor :darksalmonColor}
|
||||||
|
onValueChange={toggleSwitch}
|
||||||
|
value={isEnabled}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
</SafeAreaView>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export function themeSettings() {
|
||||||
|
const theme = useTheme();
|
||||||
|
|
||||||
|
const colors = theme.colors;
|
||||||
|
console.log("themeSettings", colors)
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
font: {
|
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: colors.background,
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
padding: 16,
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
headerText: {
|
||||||
|
color: whiteColor,
|
||||||
|
fontSize: 18,
|
||||||
|
},
|
||||||
|
settingsContainer: {
|
||||||
backgroundColor: indigo,
|
backgroundColor: indigo,
|
||||||
width: '100%',
|
margin: 16,
|
||||||
height: '100%',
|
|
||||||
},
|
},
|
||||||
text: {
|
title: {
|
||||||
fontSize: 24,
|
color: whiteColor,
|
||||||
color: 'darksalmon',
|
fontSize: 20,
|
||||||
textAlign: 'center',
|
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
marginVertical: 20,
|
marginTop: 7,
|
||||||
|
marginLeft: 15,
|
||||||
|
marginBottom: 8,
|
||||||
|
},
|
||||||
|
settingRow: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
alignItems: 'center',
|
||||||
|
paddingVertical: 12,
|
||||||
|
|
||||||
|
},
|
||||||
|
settingText: {
|
||||||
|
color: whiteColor,
|
||||||
|
marginLeft: 10,
|
||||||
|
},
|
||||||
|
img: {
|
||||||
|
marginLeft: 10,
|
||||||
|
width: 30,
|
||||||
|
height: 30,
|
||||||
|
tintColor: darksalmonColor,
|
||||||
|
},
|
||||||
|
switch: {
|
||||||
|
marginRight: 10,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return styles;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
});
|
|
@ -0,0 +1,63 @@
|
|||||||
|
|
||||||
|
import {describe,test ,expect, jest, it} from "@jest/globals";
|
||||||
|
import {CustomJoke} from "../../model/CustomJoke";
|
||||||
|
import {
|
||||||
|
CustomActionType,
|
||||||
|
getJokesCustoms,
|
||||||
|
setCustomsJoke,
|
||||||
|
setCustomsJokeById, setDeleteCustomJoke, setFavoriteJoke,
|
||||||
|
setPostJoke
|
||||||
|
} from "../../redux/actions/customAction";
|
||||||
|
|
||||||
|
|
||||||
|
describe('Action tests', () => {
|
||||||
|
it('setPostJoke creates correct action', () => {
|
||||||
|
const postJoke = new CustomJoke('test', 'Why did the chicken...', 'To get to the other side!', 'http://www.jokes.com/joke1', "1");
|
||||||
|
const expectedAction = {
|
||||||
|
type: CustomActionType.POST_CUSTOM_JOKE,
|
||||||
|
payload: postJoke,
|
||||||
|
};
|
||||||
|
expect(setPostJoke(postJoke)).toEqual(expectedAction);
|
||||||
|
});
|
||||||
|
|
||||||
|
it ('setCustomsJoke creates correct action', () => {
|
||||||
|
const customJokes = [new CustomJoke('test', 'Why did the chicken...', 'To get to the other side!', 'http://www.jokes.com/joke1', "1")];
|
||||||
|
const expectedAction = {
|
||||||
|
type: CustomActionType.FETCH_CUSTOMS_JOKE,
|
||||||
|
payload: customJokes,
|
||||||
|
};
|
||||||
|
expect(setCustomsJoke(customJokes)).toEqual(expectedAction);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
it('setCustomsJokeById creates correct action', () => {
|
||||||
|
const completCustomJoke = new CustomJoke('test', 'Why did the chicken...', 'To get to the other side!', 'http://www.jokes.com/joke1', "1");
|
||||||
|
const expectedAction = {
|
||||||
|
type: CustomActionType.FETCH_CUSTOMS_JOKE_BY_ID,
|
||||||
|
payload: completCustomJoke,
|
||||||
|
};
|
||||||
|
expect(setCustomsJokeById(completCustomJoke)).toEqual(expectedAction);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
it('setDeleteCustomJoke creates correct action', () => {
|
||||||
|
const deleteCustomJoke = new CustomJoke('test', 'Why did the chicken...', 'To get to the other side!', 'http://www.jokes.com/joke1', "1");
|
||||||
|
const expectedAction = {
|
||||||
|
type: CustomActionType.DELETE_CUSTOM_JOKE,
|
||||||
|
payload: deleteCustomJoke,
|
||||||
|
};
|
||||||
|
expect(setDeleteCustomJoke(deleteCustomJoke)).toEqual(expectedAction);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
it('setFavoriteJoke creates correct action', () => {
|
||||||
|
const favoriteJokes = [new CustomJoke('test', 'Why did the chicken...', 'To get to the other side!', 'http://www.jokes.com/joke1', "1")];
|
||||||
|
const expectedAction = {
|
||||||
|
type: CustomActionType.FETCH_FAVORITE_JOKE,
|
||||||
|
payload: favoriteJokes,
|
||||||
|
};
|
||||||
|
expect(setFavoriteJoke(favoriteJokes)).toEqual(expectedAction);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
});
|
Loading…
Reference in new issue