xcarpentier / rn-tourguide

🚩Make an interactive step by step tour guide for your react-native app (a rewrite of react-native-copilot)
https://xcarpentier.github.io/rn-tourguide/
Other
745 stars 214 forks source link

custom toolTip connecting functions #90

Closed lucidprojects closed 2 years ago

lucidprojects commented 2 years ago

I'm sure there is a trivial solution to this but I can't seem to get it worked out.

I want to customize the labels for my rn-tourguide tooltip so I have implemented a TooltipComponent as detailed in the README and I'm getting my custom labels but cannot make them do anything.

Apologies, still learning react. Any help appreciated.

Here is my code:

import React, { useEffect, useState } from "react";
import {
  View,
  Image,
  Button,
  Text,
  StyleSheet,
  TouchableOpacity,
  Animated,
  Dimensions,
} from "react-native";

import {
  TourGuideProvider,
  TourGuideZone,
  TourGuideZoneByPosition,
  useTourGuideController,
} from "rn-tourguide";

const { width, height } = Dimensions.get("window");

const TooltipComponent = ({
  isFirstStep,
  isLastStep,
  handleNext,
  handlePrev,
  handleStop,
  currentStep,
  labels,
}) => (
  <View
    style={{
      borderRadius: 16,
      paddingTop: 24,
      alignItems: "center",
      justifyContent: "center",
      paddingBottom: 16,
      width: "80%",
      backgroundColor: "#ffffffef",
    }}
  >
    <View style={styles.tooltipContainer}>
      <Text testID="stepDescription" style={styles.tooltipText}>
        {currentStep && currentStep.text}
      </Text>
    </View>
    <View style={[styles.bottomBar]}>
      {!isLastStep ? (
        <TouchableOpacity onPress={handleStop}>
          <Button title={labels?.skip || "Skip?"}> </Button>
        </TouchableOpacity>
      ) : null}
      {!isFirstStep ? (
        <TouchableOpacity onPress={handlePrev}>
          <Button title={labels?.previous || "Previous"}> </Button>
        </TouchableOpacity>
      ) : null}
      {!isLastStep ? (
        <TouchableOpacity onPress={handleNext}>
          <Button title={labels?.next || "Next"}></Button>
        </TouchableOpacity>
      ) : (
        <TouchableOpacity onPress={handleStop}>
          <Button title={labels?.finish || "Finish"}></Button>
        </TouchableOpacity>
      )}
    </View>
  </View>
);

function LocalSettingsScreen(props) {

  const { canStart, start, stop, eventEmitter } = useTourGuideController();

  useEffect(() => {
    if (canStart) {
      start();
    }
  }, [canStart]);

  const handleOnStart = () => console.log("start");
  const handleOnStop = () => {
    console.log("stop");
    moveView(0);
  };
  const handleOnStepChange = () => console.log(`stepChange`);

  useEffect(() => {
    eventEmitter.on("start", handleOnStart);
    eventEmitter.on("stop", handleOnStop);
    eventEmitter.on("stepChange", handleOnStepChange);

    return () => {
      eventEmitter.off("start", handleOnStart);
      eventEmitter.off("stop", handleOnStop);
      eventEmitter.off("stepChange", handleOnStepChange);
    };
  }, []);

  const yValue = useState(new Animated.Value(0))[0];
  let startingYValue = 0;

  function moveView(value) {
    console.log(`moving ${value}`);
    Animated.timing(yValue, {
      toValue: value,
      duration: 5,
      useNativeDriver: true,
    }).start();
  }

  return (
    <>
      <View
        style={styles.container}
      >
        <View>
          <TouchableOpacity
            onPress={() => {
              startingYValue = startingYValue + 50;
              console.log("startingYValue ", startingYValue);
              moveView(startingYValue);
            }}
          >
            <Animated.View style={{ transform: [{ translateY: yValue }] }}>
              <Image
                source={require("../../../assets/settings_walkthrough_screen.png")}
                style={styles.image}
              />
            </Animated.View>
          </TouchableOpacity>

          <TourGuideZone
            zone={0}
            text={"This is Step 1"}
            borderRadius={8}
            tooltipBottomOffset={400}
          ></TourGuideZone>
          <TourGuideZoneByPosition
            text={"This is Step 2"}
            zone={1}
            shape={"circle"}
            isTourGuide
            top={83}
            left={"2.5%"}
            width={50}
            height={50}
          />
        </View>
      </View>
      <View style={{ height: 100, width: "100%", paddingTop:0 }}>
        <View style={{ marginLeft: 0 }}>
          <Image
            resizeMode={"contain"}
            style={{
              width: "100%",
              height: "100%",
              alignSelf: "center",
            }}
            source={require("../../../assets/settings_walkthrough_screen_ft.png")}
          />
        </View>
      </View>
    </>
  );
}

export function SettingsScreen(props) {

  return (
    <View style={{ flex: 1, width: "100%" }}>
      <TourGuideProvider {...{ tooltipComponent: TooltipComponent }}>
        <LocalSettingsScreen props={props} />
      </TourGuideProvider>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
    width: "100%",
    height: "100%",
  },

  image: {
    height: "100%",
    zIndex: -1,
    width: width,
  },
  backgroundImage: {
    height: "100%",
    position: "absolute",
    top: 0,
    left: 0,
    alignItems: "center",
    bottom: 0,
    right: 0,
    width: width,
    flex: 1,
  },
});
lucidprojects commented 2 years ago

I realized the sample code was using a custom Button component, once I imported that into my code things started to play nice.

import { Button } from "../node_modules/rn-tourguide/lib/components/Button.js";