Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Nouvelle page pour désactiver le son/vibreur + Page du choix des thèmes native #566

Open
wants to merge 26 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
57e8e3f
création de la page "Son et vibrations" (issue de la page affichage)
Kgeek33 Jan 3, 2025
10ec90a
feat(Settings): ajout de la gestion des sons et vibrations dans les p…
Kgeek33 Jan 3, 2025
22a7d2e
fix(Settings): amélioration de la gestion des sons et vibrations avec…
Kgeek33 Jan 3, 2025
feca510
fix(Settings): définir les valeurs par défaut pour les sons et vibrat…
Kgeek33 Jan 3, 2025
7236173
fix(Settings): correction du nom de la variable pour la gestion des sons
Kgeek33 Jan 3, 2025
2193874
suppression du son non utilisé
Kgeek33 Jan 3, 2025
3133e9a
suppression du son non utilisé sur `FirstInstallation` et suppression…
Kgeek33 Jan 3, 2025
f21828c
feat(SoundAndHaptics): ajout d'un hook pour gérer les sons et les vib…
Kgeek33 Jan 3, 2025
b03c8cf
feat(SoundAndHaptics): intégrer la gestion des sons et vibrations dan…
Kgeek33 Jan 3, 2025
65a6364
adaptation du hook pour une actualisation automatique des paramètres !
Kgeek33 Jan 3, 2025
b476572
la page des paramètres pour changer le thème est désormais natif ! qu…
Kgeek33 Jan 3, 2025
4f645fd
Merge branch 'main' into feat/newOptions
Kgeek33 Jan 3, 2025
de54c04
fix(Settings): mettre à jour la couleur de l'icône Son et vibrations
ecnivtwelve Jan 4, 2025
1e63c04
Merge branch 'main' into feat/newOptions
Kgeek33 Jan 8, 2025
ed47599
fix(ts) errors
Kgeek33 Jan 8, 2025
325684f
Merge branch 'main' into feat/newOptions
Kgeek33 Jan 11, 2025
f576197
Merge branch 'main' into feat/newOptions
Kgeek33 Jan 17, 2025
967c987
fix: eslint errors
Kgeek33 Jan 17, 2025
8d48155
feat: ajouter un wrapper pour le son et les retours haptiques
Kgeek33 Jan 17, 2025
7b04ff0
refactor: renommer triggerHapticFeedback en playHaptics pour plus de …
Kgeek33 Jan 17, 2025
e63cee4
refactor: améliorer la fonction playSound pour utiliser un chemin de …
Kgeek33 Jan 17, 2025
be25edc
refactor: utilisation du wrapper
Kgeek33 Jan 17, 2025
487d6a5
fix: Invalid call in require
Kgeek33 Jan 17, 2025
db9c82d
refractor: utilisation du wrapper V2
Kgeek33 Jan 17, 2025
c1600b0
Merge branch 'main' into feat/newOptions
Kgeek33 Jan 18, 2025
d5e3ac7
fix: eslint errors
Kgeek33 Jan 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {AccountService, PrimaryAccount} from "@/stores/account/types";
import { log } from "@/utils/logger/logger";
import { expoGoWrapper } from "@/utils/native/expoGoAlert";
import { atobPolyfill, btoaPolyfill } from "js-base64";
import { SoundHapticsProvider } from "@/hooks/Theme_Sound_Haptics";

SplashScreen.preventAutoHideAsync();

Expand Down Expand Up @@ -128,5 +129,9 @@ export default function App () {
return null;
}

return <Router />;
return (
<SoundHapticsProvider>
<Router />
</SoundHapticsProvider>
);
}
6 changes: 5 additions & 1 deletion src/components/FirstInstallation/ButtonCta.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Text, Pressable, StyleSheet, type StyleProp, type ViewStyle } from "rea
import Reanimated, { Easing, useSharedValue, withTiming } from "react-native-reanimated";
import { useTheme } from "@react-navigation/native";
import * as Haptics from "expo-haptics";
import useSoundHapticsWrapper from "@/utils/native/playSoundHaptics";

const ButtonCta: React.FC<{
value: string
Expand All @@ -21,6 +22,7 @@ const ButtonCta: React.FC<{
backgroundColor,
icon,
}) => {
const { playHaptics } = useSoundHapticsWrapper();
const { colors } = useTheme();

const [pressed, setPressed] = useState(false);
Expand All @@ -41,7 +43,9 @@ const ButtonCta: React.FC<{
scale.value = withTiming(1, { duration: 0, easing: Easing.linear });
scale.value = withTiming(0.95, { duration: 50, easing: Easing.linear });
opacity.value = withTiming(0.7, { duration: 10, easing: Easing.linear });
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Heavy);
playHaptics("impact", {
impact: Haptics.ImpactFeedbackStyle.Heavy,
});
}
else {
scale.value = withTiming(1, { duration: 100, easing: Easing.linear });
Expand Down
18 changes: 7 additions & 11 deletions src/components/FirstInstallation/DuoListPressable.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React, { useCallback, useEffect, useState } from "react";
import React, { useEffect, useState } from "react";
import { View, Text, Pressable, StyleSheet } from "react-native";

import { useTheme } from "@react-navigation/native";
import * as Haptics from "expo-haptics";
import { Audio } from "expo-av";

import Reanimated, { Easing, useSharedValue, withTiming } from "react-native-reanimated";
import useSoundHapticsWrapper from "@/utils/native/playSoundHaptics";

const DuoListPressable: React.FC<{
children?: JSX.Element,
Expand All @@ -31,21 +31,17 @@ const DuoListPressable: React.FC<{
const scale = useSharedValue(1);
const opacity = useSharedValue(1);

const playSound = useCallback(async () => {
const { sound } = await Audio.Sound.createAsync(
require("@/../assets/sound/click_003.wav")
);
await sound.setPositionAsync(0);
await sound.playAsync();
}, []);
const { playHaptics, playSound } = useSoundHapticsWrapper();

useEffect(() => {
if (pressed) {
scale.value = withTiming(1, { duration: 0, easing: Easing.linear });
scale.value = withTiming(0.95, { duration: 50, easing: Easing.linear });
opacity.value = withTiming(0.7, { duration: 10, easing: Easing.linear });
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
playSound();
playHaptics("impact", {
impact: Haptics.ImpactFeedbackStyle.Light,
});
playSound(require("@/../assets/sound/click_003.wav"));
}
else {
scale.value = withTiming(1, { duration: 100, easing: Easing.linear });
Expand Down
10 changes: 8 additions & 2 deletions src/components/Global/PapillonCheckbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Check } from "lucide-react-native";
import * as Haptics from "expo-haptics";
import PapillonSpinner from "./PapillonSpinner";
import { animPapillon } from "@/utils/ui/animations";
import useSoundHapticsWrapper from "@/utils/native/playSoundHaptics";

interface CheckboxProps {
checked?: boolean
Expand All @@ -28,6 +29,7 @@ const PapillonCheckbox: React.FC<CheckboxProps> = ({
}) => {
const theme = useTheme();
const firstRender = useRef(true);
const { playHaptics } = useSoundHapticsWrapper();

useEffect(() => {
if (firstRender.current) {
Expand All @@ -40,14 +42,18 @@ const PapillonCheckbox: React.FC<CheckboxProps> = ({
const pressAction = () => {
onPress();

Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
playHaptics("impact", {
impact: Haptics.ImpactFeedbackStyle.Light,
});
setHasPressed(true);
};

// on checked change
useEffect(() => {
if (checked && hasPressed && loaded) {
Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success);
playHaptics("notification", {
notification: Haptics.NotificationFeedbackType.Success,
});
}
}, [checked, hasPressed]);

Expand Down
2 changes: 1 addition & 1 deletion src/components/Grades/AnimatedEmoji.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useEffect, useState } from "react";
import { View, Text } from "react-native";
import { View } from "react-native";
import Animated, {
useAnimatedStyle,
useSharedValue,
Expand Down
4 changes: 1 addition & 3 deletions src/components/Grades/GradeModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@ import {
Image,
TouchableOpacity,
Text,
Platform,
Alert
} from "react-native";
import { Download, Trash, Maximize2, Share, Delete } from "lucide-react-native";
import { Download, Trash, Share } from "lucide-react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { BlurView } from "expo-blur";
import { ScrollView } from "react-native-gesture-handler";
import * as Sharing from "expo-sharing";
import * as FileSystem from "expo-file-system";
import * as MediaLibrary from "expo-media-library";
Expand Down
15 changes: 8 additions & 7 deletions src/components/Home/AccountSwitcherContextMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { defaultProfilePicture } from "@/utils/ui/default-profile-picture";
import { useTheme } from "@react-navigation/native";
import { BlurView } from "expo-blur";
import { Check, Cog, Plus } from "lucide-react-native";
import useSoundHapticsWrapper from "@/utils/native/playSoundHaptics";

const ContextMenu: React.FC<{
style?: any;
Expand All @@ -38,6 +39,7 @@ const ContextMenu: React.FC<{
const theme = useTheme();
const { colors } = theme;
const navigation = useNavigation();
const { playHaptics } = useSoundHapticsWrapper();

const [opened, setOpened] = useState(false); // État pour gérer l'ouverture du menu contextuel

Expand All @@ -53,11 +55,6 @@ const ContextMenu: React.FC<{
}
}, [shouldOpenContextMenu]);

// Fonction pour activer un effet haptique à l'ouverture du menu
const openEffects = () => {
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
};

return (
<>
<View
Expand All @@ -74,7 +71,9 @@ const ContextMenu: React.FC<{
<TouchableOpacity
onPress={() => {
setOpened(!opened);
openEffects();
playHaptics("impact", {
impact: Haptics.ImpactFeedbackStyle.Light,
});
}}
// @ts-expect-error
pointerEvents="auto"
Expand All @@ -90,7 +89,9 @@ const ContextMenu: React.FC<{
<TouchableNativeFeedback
onPress={() => {
setOpened(!opened);
openEffects();
playHaptics("impact", {
impact: Haptics.ImpactFeedbackStyle.Light,
});
}}
useForeground={true}
style={{
Expand Down
31 changes: 31 additions & 0 deletions src/components/Settings/SoundHapticsContainerCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from "react";

import { View } from "react-native";
import { NativeItem, NativeList, NativeText } from "../Global/NativeComponents";

const ApparenceContainerCard = () => {
return (
<NativeList>
<View
style={{
height: 120,
justifyContent: "center",
alignItems: "center",
overflow: "hidden",
backgroundColor: "#1E316A22",
flexDirection: "row",
}}
>
<NativeText style={{ fontSize: 75, lineHeight: 125 }}>🔊</NativeText>
</View>
<NativeItem>
<NativeText variant="title">Son et vibrations</NativeText>
<NativeText variant="subtitle">
Par défaut, Papillon joue des sons et des vibrations mais cela peut être changé.
</NativeText>
</NativeItem>
</NativeList>
);
};

export default ApparenceContainerCard;
62 changes: 62 additions & 0 deletions src/hooks/Theme_Sound_Haptics.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import React, { createContext, useContext, useState, useEffect } from "react";
import AsyncStorage from "@react-native-async-storage/async-storage";

const SoundHapticsContext = createContext({
whatTheme: 0,
enableSon: true,
enableHaptics: true,
setWhatTheme: (value: number) => {},
setEnableSon: (value: boolean) => {},
setEnableHaptics: (value: boolean) => {},
});

export const SoundHapticsProvider = ({
children,
}: {
children: React.ReactNode;
}) => {
const [whatTheme, setWhatTheme] = useState(0);
const [enableSon, setEnableSon] = useState(true);
const [enableHaptics, setEnableHaptics] = useState(true);

useEffect(() => {
AsyncStorage.getItem("theme").then((value) =>
setWhatTheme(parseInt(value ?? "0"))
);
AsyncStorage.getItem("son").then((value) =>
setEnableSon(value === "true" || value === null)
);
AsyncStorage.getItem("haptics").then((value) =>
setEnableHaptics(value === "true" || value === null)
);
}, []);

useEffect(() => {
AsyncStorage.setItem("theme", String(whatTheme));
}, [whatTheme]);

useEffect(() => {
AsyncStorage.setItem("son", String(enableSon));
}, [enableSon]);

useEffect(() => {
AsyncStorage.setItem("haptics", String(enableHaptics));
}, [enableHaptics]);

return (
<SoundHapticsContext.Provider
value={{
whatTheme,
enableSon,
enableHaptics,
setWhatTheme,
setEnableSon,
setEnableHaptics,
}}
>
{children}
</SoundHapticsContext.Provider>
);
};

export const useThemeSoundHaptics = () => useContext(SoundHapticsContext);
1 change: 1 addition & 0 deletions src/router/helpers/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ export type RouteParameters = {
SettingsDonorsList: undefined;
SettingsReactions: undefined;
SettingsApparence: undefined;
SettingsSoundHaptics: undefined;

Menu?: undefined;
RestaurantQrCode: {
Expand Down
20 changes: 6 additions & 14 deletions src/router/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@ import { useCurrentAccount } from "@/stores/account";
import { navigatorScreenOptions } from "./helpers/create-screen";
import {navigate} from "@/utils/logger/logger";
import { PapillonNavigation } from "./refs";
import AsyncStorage from "@react-native-async-storage/async-storage";
import { useThemeSoundHaptics } from "@/hooks/Theme_Sound_Haptics";

export const Stack = createNativeStackNavigator<RouteParameters>();

const Router: React.FC = () => {
const scheme = useColorScheme();
const { whatTheme } = useThemeSoundHaptics();

useEffect(() => {
async function setNavigationBar () {
Expand All @@ -47,19 +48,10 @@ const Router: React.FC = () => {
config,
};

const [themeValue, setThemeValue] = React.useState<number>(0);

const [theme, setTheme] = React.useState<Theme>(scheme === "dark" ? PapillonDark : PapillonLight);

useEffect(() => {
AsyncStorage.getItem("theme").then((value) => {
if (value)
setThemeValue(parseInt(value));
});
}, []);

useEffect(() => {
switch (themeValue) {
switch (whatTheme) {
case 0:
setTheme(scheme === "dark" ? PapillonDark : PapillonLight);
break;
Expand All @@ -70,7 +62,7 @@ const Router: React.FC = () => {
setTheme(PapillonDark);
break;
}
}, [scheme, themeValue]);
}, [scheme, whatTheme]);


const account = useCurrentAccount(store => store.account!);
Expand All @@ -88,13 +80,13 @@ const Router: React.FC = () => {
backgroundColor={"transparent"}
translucent={true}
barStyle={
themeValue == 0 ?
whatTheme === 0 ?
scheme === "dark" ?
"light-content"
:
"dark-content"
:
themeValue == 1 ?
whatTheme === 1 ?
"dark-content"
:
"light-content"
Expand Down
15 changes: 8 additions & 7 deletions src/router/navigator/atoms/MenuItem.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import * as React from "react";
import { useCurrentAccount } from "@/stores/account";
import { useNavigationBuilder, useTheme } from "@react-navigation/native";
import { StyleSheet, View, Text, Platform } from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { useTheme } from "@react-navigation/native";
import { StyleSheet, Platform } from "react-native";
import LottieView from "lottie-react-native";
import colorsList from "@/utils/data/colors.json";
import { Pressable } from "react-native-gesture-handler";
import * as Haptics from "expo-haptics";
import Reanimated, { FadeIn, FadeOut, LinearTransition, ZoomIn } from "react-native-reanimated";
import Reanimated, { FadeIn, FadeOut, LinearTransition } from "react-native-reanimated";
import { anim2Papillon } from "@/utils/ui/animations";
import useSoundHapticsWrapper from "@/utils/native/playSoundHaptics";

const MenuItem: React.FC<{
route: any;
Expand All @@ -17,6 +16,7 @@ const MenuItem: React.FC<{
isFocused: boolean;
}> = ({ route, descriptor, navigation, isFocused }) => {
const theme = useTheme();
const { playHaptics } = useSoundHapticsWrapper();

const { options } = descriptor;
const label = options.tabBarLabel !== undefined ? options.tabBarLabel : options.title !== undefined ? options.title : route.name;
Expand All @@ -33,8 +33,9 @@ const MenuItem: React.FC<{
}

lottieRef.current?.play();
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);

playHaptics("impact", {
impact: Haptics.ImpactFeedbackStyle.Light,
});
};

const onLongPress = () => {
Expand Down
Loading
Loading