diff --git a/.drone.yml b/.drone.yml index 7f1dcbe..29b8fb3 100644 --- a/.drone.yml +++ b/.drone.yml @@ -12,7 +12,8 @@ steps: commands: - cd ./LeftOvers/ - npm install - - npm run + - npx react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/res/raw/index.android.bundle --assets-dest android/app/src/main/res/ + - name: code-analysis image: node:latest diff --git a/LeftOvers/Services/Profiles/IProfileService.ts b/LeftOvers/Services/Profiles/IProfileService.ts new file mode 100644 index 0000000..a3fdfe6 --- /dev/null +++ b/LeftOvers/Services/Profiles/IProfileService.ts @@ -0,0 +1,7 @@ +import Profil from "../../Models/Profil"; + +export default interface IProfileService { + getProfiles(): Promise, + addProfile(new_profile: Profil): Promise, + delProfile(profile_name_to_del: String): Promise +} \ No newline at end of file diff --git a/LeftOvers/Services/Profiles/ProfileService.ts b/LeftOvers/Services/Profiles/ProfileService.ts new file mode 100644 index 0000000..e013180 --- /dev/null +++ b/LeftOvers/Services/Profiles/ProfileService.ts @@ -0,0 +1,41 @@ +import Profil from "../../Models/Profil"; +import IProfileService from "./IProfileService"; +import AsyncStorage from "@react-native-async-storage/async-storage"; + +export default class ProfileService implements IProfileService { + async getProfiles(): Promise { + const results = await AsyncStorage.getItem('profiles'); + const tmp = JSON.parse(results) + let existingProfiles: Profil[] = [] + for (let item of tmp) { + existingProfiles.push(new Profil(item._name, item._avatar, item._allergy, item._diets)) + } + return existingProfiles; + } + + async addProfile(new_profile : Profil): Promise { + const existingProfiles = await this.getProfiles() + for (let current_profile of existingProfiles) { + if (current_profile.name == new_profile.name) { + console.log("Tried to create a profil already existing !") + return false + } + } + await AsyncStorage.setItem('profiles', JSON.stringify([...existingProfiles, new_profile])) + return true + } + + async delProfile(profile_name_to_del: String): Promise { + const existing_profiles = await this.getProfiles() + let key: number = -1 + for (let current_profile of existing_profiles) { + if (current_profile.name == profile_name_to_del) { + let updated_profile = existing_profiles.splice(key, 1) + await AsyncStorage.setItem('profiles', JSON.stringify(updated_profile)) + return true + } + key ++ + } + return false + } +} \ No newline at end of file diff --git a/LeftOvers/android/app/src/main/res/raw/placeholder.txt b/LeftOvers/android/app/src/main/res/raw/placeholder.txt new file mode 100644 index 0000000..e69de29 diff --git a/LeftOvers/components/FoodElementText.tsx b/LeftOvers/components/FoodElementText.tsx index 2da10b3..5928ee2 100644 --- a/LeftOvers/components/FoodElementText.tsx +++ b/LeftOvers/components/FoodElementText.tsx @@ -14,8 +14,8 @@ const componentHeight = 60; const componentWidth = 280; -export default function FoodElementText(props : any) { - const {colors} = useContext(ColorContext) +export default function FoodElementText(props : foodElementImageProps) { + const colors = useContext(ColorContext).colors const styles = StyleSheet.create({ button: { diff --git a/LeftOvers/components/ListSelect.tsx b/LeftOvers/components/ListSelect.tsx index 24bf043..2f33ee7 100644 --- a/LeftOvers/components/ListSelect.tsx +++ b/LeftOvers/components/ListSelect.tsx @@ -1,6 +1,6 @@ import React, { useContext } from 'react'; -import {StyleSheet, Image} from 'react-native'; -import {MultipleSelectList} from 'react-native-dropdown-select-list' +import { StyleSheet, Image } from 'react-native'; +import { MultipleSelectList } from 'react-native-dropdown-select-list' import ColorContext from '../theme/ColorContext'; type ListProps = { @@ -11,8 +11,8 @@ type ListProps = { } export default function ListSelect(props: ListProps) { - - const {colors} = useContext(ColorContext); + const [selected, setSelected] = React.useState([]); + const colors = useContext(ColorContext).colors; const styles = StyleSheet.create({ titleBar: { diff --git a/LeftOvers/components/ListWithoutSelect.tsx b/LeftOvers/components/ListWithoutSelect.tsx index 1944867..a095f3c 100644 --- a/LeftOvers/components/ListWithoutSelect.tsx +++ b/LeftOvers/components/ListWithoutSelect.tsx @@ -1,6 +1,6 @@ import React, { useContext } from 'react'; -import {StyleSheet, Image} from 'react-native'; -import {MultipleSelectList} from 'react-native-dropdown-select-list' +import { StyleSheet, Image } from 'react-native'; +import { MultipleSelectList } from 'react-native-dropdown-select-list' import ColorContext from '../theme/ColorContext'; type ListProps = { @@ -10,8 +10,7 @@ type ListProps = { export default function ListWithoutSelect(props: ListProps) { const [selected, setSelected] = React.useState([]); - const { colors } = useContext(ColorContext); - + const colors = useContext(ColorContext).colors; const styles = StyleSheet.create({ titleBar: { diff --git a/LeftOvers/components/ProfileDetails.tsx b/LeftOvers/components/ProfileDetails.tsx index 777397f..2bb2c0b 100644 --- a/LeftOvers/components/ProfileDetails.tsx +++ b/LeftOvers/components/ProfileDetails.tsx @@ -1,5 +1,6 @@ import React, { useContext, useState } from 'react'; import { StyleSheet, Text, View, Image, Pressable } from 'react-native'; +import { useNavigation } from '@react-navigation/native'; import ListWithoutSelect from './ListWithoutSelect'; import ColorContext from '../theme/ColorContext'; @@ -14,7 +15,8 @@ type ProfileProps = { } export default function ProfileDetails(props) { - const { colors } = useContext(ColorContext) + const colors = useContext(ColorContext).colors + const navigation = useNavigation() const [display, setDisplay] = useState("none") const changeListVisibility = () => { if (display == "none"){ diff --git a/LeftOvers/components/ProfileElement.tsx b/LeftOvers/components/ProfileElement.tsx index c75b8d9..2f4f0d9 100644 --- a/LeftOvers/components/ProfileElement.tsx +++ b/LeftOvers/components/ProfileElement.tsx @@ -10,7 +10,7 @@ type Profile = { } export default function ProfileElement(props : Profile) { - const { colors } = useContext(ColorContext) + const colors = useContext(ColorContext).colors const [waiting, setWaiting] = useState("none") const [separator, setSeparator] = useState("none") diff --git a/LeftOvers/components/ProfileModification.tsx b/LeftOvers/components/ProfileModification.tsx index d738e9a..11c4527 100644 --- a/LeftOvers/components/ProfileModification.tsx +++ b/LeftOvers/components/ProfileModification.tsx @@ -15,7 +15,7 @@ type ProfileProps = { export default function ProfileModification(props: ProfileProps) { const [name, onChangeName] = useState(props.name); - const { colors } = useContext(ColorContext); + const colors = useContext(ColorContext).colors; let imageSource if (props.avatar == "plus.png"){ diff --git a/LeftOvers/components/ProfileSelection.tsx b/LeftOvers/components/ProfileSelection.tsx index a750033..f748365 100644 --- a/LeftOvers/components/ProfileSelection.tsx +++ b/LeftOvers/components/ProfileSelection.tsx @@ -20,7 +20,7 @@ type Profile = { } export default function ProfileSelection(props: ProfileSelectionProps) { - const { colors } = useContext(ColorContext); + const colors = useContext(ColorContext).colors; const [cpt, setCpt] = useState(0); const decreaseCounter = () => { diff --git a/LeftOvers/navigation/BottomBar.tsx b/LeftOvers/navigation/BottomBar.tsx index c2484bf..a65c78d 100644 --- a/LeftOvers/navigation/BottomBar.tsx +++ b/LeftOvers/navigation/BottomBar.tsx @@ -15,7 +15,7 @@ import DarkIcon from '../assets/images/moon.png'; export default function BottomBar({ state, descriptors, navigation }) { const {theme, toggleTheme} = useContext(ThemeContext); - const {colors, toggleColors} = useContext(ColorContext) + const { colors, toggleColors } = useContext(ColorContext); const [iconThemeButton, setThemeIconButton] = useState(( theme === 'dark' ) ? LightIcon : DarkIcon) const [textThemeButton, setTextThemeButton] = useState(( theme === 'dark' ) ? 'Light' : 'Dark'); @@ -47,10 +47,10 @@ export default function BottomBar({ state, descriptors, navigation }) { flexDirection: 'row', alignItems: 'center', alignContent: 'space-around', - borderBlockColor: theme === 'light' ? '#F2F0E4' : '#222222', + borderBlockColor: colors.blocBorder, borderWidth: 2, - borderLeftColor: theme === 'light'? '#F2F0E4' : '#222222', - borderRightColor: theme === 'light'? '#F2F0E4' : '#222222', + borderLeftColor: colors.blocBorder, + borderRightColor: colors.blocBorder, }, BottomBarIcon: { width: 25, diff --git a/LeftOvers/navigation/CookingStackScreen.tsx b/LeftOvers/navigation/CookingStackScreen.tsx index 669a8b2..978c45e 100644 --- a/LeftOvers/navigation/CookingStackScreen.tsx +++ b/LeftOvers/navigation/CookingStackScreen.tsx @@ -1,5 +1,4 @@ import React, { useContext } from 'react' -import { StyleSheet } from 'react-native' import { createNativeStackNavigator } from '@react-navigation/native-stack'; import IngredientSelection from '../screens/IngredientSelection'; @@ -11,7 +10,7 @@ import RecipeDetails from '../screens/RecipeDetails'; const CookingStack = createNativeStackNavigator() export default function CookingStackScreen() { - const {theme} = useContext(ThemeContext); + const theme = useContext(ThemeContext).theme; return ( @@ -47,10 +46,4 @@ export default function CookingStackScreen() { /> ) -} - -const styles = StyleSheet.create({ - headerBarContainer: { - backgroundColor: '#F2F0E4', - }, -}) \ No newline at end of file +} \ No newline at end of file diff --git a/LeftOvers/navigation/HomeStackScreen.tsx b/LeftOvers/navigation/HomeStackScreen.tsx index 512369d..4f9c293 100644 --- a/LeftOvers/navigation/HomeStackScreen.tsx +++ b/LeftOvers/navigation/HomeStackScreen.tsx @@ -25,7 +25,7 @@ function AppIcon() { } export default function HomeStackScreen() { - const {colors} = useContext(ColorContext) + const colors = useContext(ColorContext).colors return ( diff --git a/LeftOvers/navigation/ProfileStackScreen.tsx b/LeftOvers/navigation/ProfileStackScreen.tsx index b1c1e4e..5f55471 100644 --- a/LeftOvers/navigation/ProfileStackScreen.tsx +++ b/LeftOvers/navigation/ProfileStackScreen.tsx @@ -5,7 +5,7 @@ import { createNativeStackNavigator } from '@react-navigation/native-stack'; import Profiles from '../screens/Profiles'; import CreateProfile from '../screens/CreateProfile'; import ModifyProfile from '../screens/ModifyProfile'; -import ThemeContext from '../theme/ThemeContext'; +import ColorContext from '../theme/ColorContext'; import { HeaderTitle } from './Utils'; @@ -15,11 +15,11 @@ import AddIcon from '../assets/images/plus.png' const ProfilesStack = createNativeStackNavigator() export default function ProfilesStackScreen({ navigation }) { - const {theme} = useContext(ThemeContext); + const colors = useContext(ColorContext).colors; const styles = StyleSheet.create({ headerBarContainer: { - backgroundColor: theme === 'light' ? '#F2F0E4' : '#3F3C42', + backgroundColor: colors.cardBackground, }, headerBarRightContainer: { display: 'flex', @@ -55,13 +55,13 @@ export default function ProfilesStackScreen({ navigation }) { + tintColor={colors.cardDetail}/> + tintColor={colors.cardDetail}/> ) diff --git a/LeftOvers/navigation/Utils.tsx b/LeftOvers/navigation/Utils.tsx index 557d67b..4a3a9bc 100644 --- a/LeftOvers/navigation/Utils.tsx +++ b/LeftOvers/navigation/Utils.tsx @@ -4,7 +4,7 @@ import { Text, StyleSheet } from 'react-native'; import ColorContext from '../theme/ColorContext'; export function HeaderTitle(props) { - const {colors} = useContext(ColorContext) + const colors = useContext(ColorContext).colors const styles = StyleSheet.create({ headerTitle: { diff --git a/LeftOvers/screens/CreateProfile.tsx b/LeftOvers/screens/CreateProfile.tsx index 3091efb..5eb2769 100644 --- a/LeftOvers/screens/CreateProfile.tsx +++ b/LeftOvers/screens/CreateProfile.tsx @@ -6,18 +6,20 @@ import ValidateButton from '../components/ValidateButton'; import ColorContext from '../theme/ColorContext'; import ListWithoutSelect from '../components/ListWithoutSelect'; import ListSelect from '../components/ListSelect'; -import AsyncStorage from '@react-native-async-storage/async-storage'; import EventEmitter from './EventEmitter'; import * as ImagePicker from 'expo-image-picker'; +import ProfileService from '../Services/Profiles/ProfileService'; +import AsyncStorage from '@react-native-async-storage/async-storage'; export default function CreateProfile(props) { - const { colors } = useContext(ColorContext) - const all = [] + const colors = useContext(ColorContext).colors + const profile_service = new ProfileService() const die = [{value: "Dairy free"}, {value: "Gluten free"}, {value: "Porkless"}, {value: "Vegan"}, {value: "Vegetarian"}, {value: "Pescatarian"}] const [name, onChangeName] = useState(); const [avatar, setAvatar] = useState(''); const [selectedDiets, setSelectedDiets] = useState([]); + const [selectedAllergies, setSelectedAllergies] = useState([]) const handleSelectedDiets = (selectedValues) => { setSelectedDiets(selectedValues); @@ -26,16 +28,16 @@ export default function CreateProfile(props) { const pickImage = async () => { // No permissions request is necessary for launching the image library let result = await ImagePicker.launchImageLibraryAsync({ - mediaTypes: ImagePicker.MediaTypeOptions.All, - allowsEditing: true, - aspect: [4, 3], - quality: 1, + mediaTypes: ImagePicker.MediaTypeOptions.All, + allowsEditing: true, + aspect: [4, 3], + quality: 1, }); console.log(result); if (!result.canceled) { - setAvatar(result.assets[0].uri); + setAvatar(result.assets[0].uri); } }; @@ -68,7 +70,7 @@ export default function CreateProfile(props) { console.log('Profil créé :', newProfile); props.navigation.goBack(); } catch (error) { - console.error('Erreur lors de la création du profil :', error); + console.error('Erreur lors de la création du profil :', error); } }; @@ -167,7 +169,7 @@ export default function CreateProfile(props) { - + diff --git a/LeftOvers/screens/HomePage.tsx b/LeftOvers/screens/HomePage.tsx index bfc5298..0206991 100644 --- a/LeftOvers/screens/HomePage.tsx +++ b/LeftOvers/screens/HomePage.tsx @@ -7,6 +7,8 @@ import ValidateButton from '../components/ValidateButton'; import ProfileSelection from '../components/ProfileSelection'; import FoodElementText from '../components/FoodElementText'; import ColorContext from '../theme/ColorContext'; +import ProfileService from '../Services/Profiles/ProfileService'; +import Profil from '../Models/Profil'; import bracketLeft from '../assets/images/angle_bracket_left.png'; import bracketRight from '../assets/images/angle_bracket_right.png'; @@ -15,7 +17,8 @@ import AsyncStorage from '@react-native-async-storage/async-storage'; import EventEmitter from './EventEmitter'; export default function HomePage({ navigation, props }) { - const {colors} = useContext(ColorContext); + const colors = useContext(ColorContext).colors + const profile_service = new ProfileService() const profilesHand = [ {name: "None", avatar: "logo.png", isActive: "none"} diff --git a/LeftOvers/screens/IngredientSelection.tsx b/LeftOvers/screens/IngredientSelection.tsx index 9b9c24f..75d6dae 100644 --- a/LeftOvers/screens/IngredientSelection.tsx +++ b/LeftOvers/screens/IngredientSelection.tsx @@ -2,24 +2,27 @@ import React, { useEffect, useState, useContext } from 'react'; import { View, StyleSheet, Text, Image, Pressable, ActivityIndicator, FlatList, useWindowDimensions } from 'react-native'; import { SafeAreaProvider } from 'react-native-safe-area-context'; import { Searchbar } from 'react-native-paper'; +import { LinearGradient } from 'expo-linear-gradient'; + import FoodElementText from '../components/FoodElementText'; -import plus from '../assets/images/plus.png'; -import moins from '../assets/images/minus.png'; import Ingredient from '../Models/Ingredient'; import IngredientService from '../Services/Ingredients/IngredientsServices'; -import { LinearGradient } from 'expo-linear-gradient'; import ColorContext from '../theme/ColorContext'; import ValidateButton from '../components/ValidateButton'; import AsyncStorage from '@react-native-async-storage/async-storage'; import EventEmitter from './EventEmitter'; +import plus from '../assets/images/plus.png'; +import moins from '../assets/images/minus.png'; + export default function IngredientSelection(props) { + const colors = useContext(ColorContext).colors + const alphabetArray: Array = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]; const [isLoading, setIsLoading] = useState(true); const [response, setResponse] = useState(undefined); const [selectedIngredients, setSelectedIngredients] = useState([]); const ingredientService = new IngredientService(); - const {colors} = useContext(ColorContext); const [availableSize, setAvailableSize] = useState(0); const [listVisibility, setListVisibility] = useState("flex"); const [availableVisibility, setAvailableVisibility] = useState("none"); diff --git a/LeftOvers/screens/Profiles.tsx b/LeftOvers/screens/Profiles.tsx index c73af58..e26f939 100644 --- a/LeftOvers/screens/Profiles.tsx +++ b/LeftOvers/screens/Profiles.tsx @@ -9,9 +9,15 @@ import ColorContext from '../theme/ColorContext'; import AsyncStorage from '@react-native-async-storage/async-storage'; import EventEmitter from './EventEmitter'; import { PaperProvider, Portal } from 'react-native-paper'; +import ProfileService from '../Services/Profiles/ProfileService'; export default function Profiles({navigation, props}) { - const { colors } = useContext(ColorContext) + const colors = useContext(ColorContext).colors + const profile_service = new ProfileService() + + const all = [] + const die = [{value: "Dairy free"}, {value: "Gluten free"}, {value: "Porkless"}, {value: "Vegan"}, {value: "Vegetarian"}, {value: "Pescatarian"}] + const [visible, setVisible] = useState(false); const [profiles, setProfiles] = useState([]); const [selectedProfileIndex, setSelectedProfileIndex] = useState(null); @@ -37,10 +43,10 @@ export default function Profiles({navigation, props}) { } }; - const handleGetProfiles = async () => { + const handleGetProfiles = async () => { try { - const existingProfiles = await AsyncStorage.getItem('profiles'); - return JSON.parse(existingProfiles) || []; + const results = await profile_service.getProfiles() + return results } catch (error) { console.log(error); return []; @@ -63,9 +69,7 @@ export default function Profiles({navigation, props}) { const containerStyle = { height: "75%", width: "100%", - }; - - + }; const styles = StyleSheet.create({ container: { height: "100%",