All files / apps/host/src/screens/Profile/hooks useProfileSteps.ts

82.35% Statements 28/34
61.11% Branches 11/18
77.77% Functions 7/9
82.35% Lines 28/34

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100                      3x 3x 3x 3x                             3x 6x 6x 6x 6x   6x 3x       3x     6x   3x 2x 2x     1x 1x           6x   6x         3x                 6x 2x       2x         2x     6x 2x     6x                  
import { useCallback, useContext, useMemo, useState } from 'react';
import { type ImageSourcePropType, PanResponder } from 'react-native';
 
import { NavigationContext } from '@react-navigation/native';
 
import { SCREENS } from '@repo/constants/screens';
 
import { ASSETS } from '@/constants/assets';
 
export type ProfileStep = 'incoming' | 'my' | 'settings';
 
const PROFILE_STEPS: ProfileStep[] = ['incoming', 'my', 'settings'];
const SWIPE_ACTIVATION_DISTANCE = 12;
const SWIPE_TRIGGER_DISTANCE = 56;
const PROFILE_STEP_HEADER: Record<ProfileStep, { title: string; image: ImageSourcePropType }> = {
  incoming: {
    title: 'Incoming Requests',
    image: ASSETS.IMAGES.PROFILE.COFFEE,
  },
  my: {
    title: 'My Requests',
    image: ASSETS.IMAGES.PROFILE.RELAX,
  },
  settings: {
    title: 'Settings',
    image: ASSETS.IMAGES.PROFILE.COFFEE,
  },
};
 
export const useProfileSteps = () => {
  const navigation = useContext(NavigationContext);
  const [activeStepIndex, setActiveStepIndex] = useState(0);
  const activeStep = PROFILE_STEPS[activeStepIndex] ?? PROFILE_STEPS[0];
  const activeHeader = PROFILE_STEP_HEADER[activeStep];
 
  const updateStepIndex = useCallback((nextIndex: number) => {
    Iif (nextIndex < 0 || nextIndex >= PROFILE_STEPS.length) {
      return;
    }
 
    setActiveStepIndex(nextIndex);
  }, []);
 
  const handleSwipeStep = useCallback(
    (dx: number) => {
      if (dx <= -SWIPE_TRIGGER_DISTANCE) {
        updateStepIndex(activeStepIndex + 1);
        return;
      }
 
      Eif (dx >= SWIPE_TRIGGER_DISTANCE && activeStepIndex > 0) {
        updateStepIndex(activeStepIndex - 1);
      }
    },
    [activeStepIndex, updateStepIndex],
  );
 
  const panResponder = useMemo(
    () =>
      PanResponder.create({
        onMoveShouldSetPanResponder: (_, gestureState) =>
          Math.abs(gestureState.dx) > Math.abs(gestureState.dy) &&
          Math.abs(gestureState.dx) > SWIPE_ACTIVATION_DISTANCE,
        onPanResponderRelease: (_, gestureState) => {
          handleSwipeStep(gestureState.dx);
        },
        onPanResponderTerminate: (_, gestureState) => {
          handleSwipeStep(gestureState.dx);
        },
      }),
    [handleSwipeStep],
  );
 
  const navigateToHome = useCallback(() => {
    Iif (!navigation) {
      return;
    }
 
    Iif (navigation.canGoBack()) {
      navigation.goBack();
      return;
    }
 
    navigation.navigate(SCREENS.HOME_V2);
  }, [navigation]);
 
  const handleBackStep = useCallback(() => {
    navigateToHome();
  }, [navigateToHome]);
 
  return {
    activeStep,
    activeStepIndex,
    activeHeader,
    profileSteps: PROFILE_STEPS,
    panHandlers: panResponder.panHandlers,
    handleBackStep,
  };
};