Class

LearnTopicSingleScreenHooksApi

LearnTopicSingleScreenHooksApi()

Learn Topic Screen Hooks. Instance name: learnTopicSingleScreenApi

You can use this hook to customize the learn topic screen such as by adding a component by the topic content.

Constructor

# new LearnTopicSingleScreenHooksApi()

Example
externalCodeSetup.learnTopicSingleScreenApi.METHOD_NAME

Methods

# setAfterContentRenderer(renderFunction)

It adds a component after the topic content so you can customize the information to be displayed.

Parameters:
Name Type Description
renderFunction LearnTopicAfterContentRendererFunction
Example
externalCodeSetup.learnTopicSingleScreenApi.setAfterContentRenderer((topicObject, global, colors, navigation) => (
   <TouchableOpacity onPress={() => navigation.navigate("CoursesScreen")}>
    <Text style={{fontSize: 12}}> Tap to go back to courses list</Text>
   </TouchableOpacity>
 ))

# setAfterMaterialsComponent(AfterMaterialsComponent)

You can use this hook to add a component at the bottom of the topic single screen just after the component that displays the materials.

Parameters:
Name Type Description
AfterMaterialsComponent React.ComponentType.<LearnTopicAfterMaterialsComponentProps>
Example
//In custom_code/components/TopicBottomComponent.js...

import React from "react";
import { View, Text, TouchableOpacity } from "react-native";

const TopicBottomComponent = props => {

    const {
        colors,
        course,
        materials,
        navigation
    } = props;

    const back = () => {
        navigation.navigate({
            routeName: "CoursesSingleScreen",
            params: {
                id: course.id,
                course
            },
            key: course.id.toString()
        })
    }
    return <View style={{
        backgroundColor: colors.bodyFrontBg,
        paddingHorizontal: 20,
        paddingBottom: 20,
        minHeight: 100,
    }}>
        <Text>This lesson is part of the {course.title.rendered} course </Text>
        <TouchableOpacity onPress={back}>
            <Text>
                Back To Course
            </Text>
        </TouchableOpacity>
    </View>
}

export default TopicBottomComponent;

 //In custom_code/index.js...

 ...

import TopicBottomComponent from "./components/TopicBottomComponent";
export const applyCustomCode = externalCodeSetup => {
  externalCodeSetup.learnTopicSingleScreenApi.setAfterMaterialsComponent(props => <TopicBottomComponent {...props}/>)
}

# setLearnTopicActionComponent(LearnTopicActionComponent)

You can use this hook to customize the "Mark Complete" / "Completed" button. For example, you can add your own loading animation when the "Mark Complete" button is pressed.

Parameters:
Name Type Description
LearnTopicActionComponent React.ComponentType.<LearnTopicActionComponentProps>
Example
//In custom_code/components/LearnTopicActionComponent.js...

import React from "react";
import { View, Text, ActivityIndicator } from "react-native";

import AuthWrapper from "@src/components/AuthWrapper";
import AppTouchableOpacity from "@src/components/AppTouchableOpacity";
import Icon from "@src/components/Icon";
import { isColorDark } from "@src/utils";

const LearnTopicActionComponent = ({
  showComplete,
  global,
  colors,
  t,
  topicVM,
  onCompleteTopicClick,
  completing,
  completeDisabled
}) => (
  <AuthWrapper actionOnGuestLogin={"hide"}>
    {showComplete && (
      <View
        style={[
          global.row,
          {
            backgroundColor: colors.bodyFrontBg,
            borderTopColor: colors.borderColor
          },
          global.learnTopicActionButtonContainer
        ]}
      >
        <AppTouchableOpacity
          style={[
            {flex: 1},
            {
              opacity: !topicVM.completed && completeDisabled ? 0.5 : 1,
              backgroundColor: !topicVM.completed
                ? colors.primaryButtonBg
                : colors.bodyFrontBg
            },
            global.completeTopicButtonW
          ]}
          disabled={topicVM.completed || completeDisabled}
          onPress={onCompleteTopicClick}
        >
          <View style={global.row}>
            <View style={global.linkWithArrow}>
              {!topicVM.completed ? (
                completing && (
                  <ActivityIndicator
                    animating={true}
                    color={colors.primaryButtonColor}
                    size="small"
                    style={global.learnTopicButtonLoadingIcon}
                  />
                )
              ) : (
                <Icon
                  webIcon={""}
                  icon={require("@src/assets/img/completed-course.png")}
                  styles={global.learnTopicActionCompleteIcon}
                />
              )}
              <Text
                style={[
                  {
                    marginLeft: 10,
                    color: !topicVM.completed
                      ? colors.primaryButtonColor
                      : isColorDark(colors.bodyFrontBg)
                        ? "white"
                        : "black"
                  },
                  global.completeTopicButton
                ]}
              >
                {t(
                  topicVM.completed
                    ? "lessonTopic:completed"
                    : "lessonTopic:markAsComplete"
                )}
              </Text>
            </View>
          </View>
        </AppTouchableOpacity>
      </View>
    )}
  </AuthWrapper>
);

export default LearnTopicActionComponent;

//In custom_code/index.js...

...

import LearnTopicActionComponent from "./components/LearnTopicActionComponent";
export const applyCustomCode = (externalCodeSetup: any) => {
    externalCodeSetup.learnTopicSingleScreenApi.setLearnTopicActionComponent(props => <LearnTopicActionComponent {...props} />)
}

# setLearnTopicScreenHeader(LearnTopicScreenHeader)

You can use this hook to customize the header of the Learn Topic Single Screen which by default, contains the back-to-course button and the previous/next buttons.

Parameters:
Name Type Description
LearnTopicScreenHeader React.ComponentType.<LearnTopicScreenHeaderProps>
Example
//In custom_code/components/LearnTopicHeader.js...

import React from "react";
import {View, Text} from "react-native";
import Animated from "react-native-reanimated";
import {DEVICE_WIDTH} from "@src/styles/global";
import AuthWrapper from "@src/components/AuthWrapper";

const Header = ({
    headerLeftStyle,
    style,
    global,
    backToCourse,
    renderTimer,
    headerRightAuthWrapperProps,
    prevNext,
    topic
}) => {
  return (
    <Animated.View
      style={[
        global.row,
        global.fakeHeader,
        {
          backgroundColor: "transparent",
          paddingHorizontal: 10,
          overflow: "hidden"
        },
        {
          width: DEVICE_WIDTH
        },
        style
      ]}
    >
      <View
        style={[
          {
            alignItems: "center",
            justifyContent: "center",
            flexDirection: "row",
            flex: 1,
            height: "100%",

            backgroundColor: "cyan",
            borderRadius: 20
          }
        ]}
      >
        <View style={[global.headerButtonLeft, headerLeftStyle]}>
          {backToCourse}
        </View>

        <View>
          <Text>
            {topic.title}
          </Text>
        </View>

        <View style={[global.headerCustomTitle]}>
          {renderTimer}
        </View>
        <View style={[global.headerButtonRight]}>
          <AuthWrapper
            actionOnGuestLogin={"hide"}
            {...headerRightAuthWrapperProps}
          >
            {prevNext}
          </AuthWrapper>
        </View>
      </View>
    </Animated.View>
  );
};

export default Header;

//In custom_code/index.js...

import LearnTopicHeader from "./components/LearnTopicHeader"
export const applyCustomCode = externalCodeSetup => {
  externalCodeSetup.learnTopicSingleScreenApi.LearnTopicScreenHeader(props => <LearnTopicHeader {...props} />)
}

# setLearnTopicTitleComponent(LearnTopicTitleComponent)

You can use this to replace the topic's title component. For example, you can use this to change the subtitle's color.

Parameters:
Name Type Description
LearnTopicTitleComponent React.ComponentType.<LearnTopicTitleComponentProps>
Example

Change subtitle colors

//In custom_code/components/TopicTitle.js...
import React from "react";
import {View, Text} from "react-native";
import Animated from "react-native-reanimated";

const TopicTitle = ({
 topic,
 global,
 colors,
 paddingTop,
 setHeaderHeight,
 t,
 labels,
 lessonOrder
}) => {

  const paddingBottom = 14;

  return (
    <Animated.View
      style={[
       {
         backgroundColor: colors.bodyFrontBg,
         width: "100%",
         shadowOffset: {width: 0, height: 1},
         shadowRadius: 1,
         shadowColor: "#000",
         shadowOpacity: 0.05
       }
      ]}
    >
    <View
      style={[
        global.row,
        {
          justifyContent: "space-between",
          alignItems: "flex-start",
          paddingTop,
          paddingBottom
        }
      ]}
      onLayout={event => {
        const {height} = event.nativeEvent.layout;
        typeof setHeaderHeight === "function" && setHeaderHeight(height);
      }}
    >
      <Animated.View
        style={{
          flex: 1,
          paddingHorizontal: 20
        }}
      >
        <Animated.Text
          style={[
            global.courseHeaderTitle,
            {marginBottom: 5}
          ]}
        >
          {topic.title}
        </Animated.Text>

        <View style={global.row}>
          <Text style={[global.courseHeaderSubTitle, {color: "red"}]}>
            {t("lessonTopic:lessoncount", {
              lesson: labels.lesson,
              current: lessonOrder + 1
            })}
          </Text>
          <View
            style={{
              width: 3,
              height: 3,
              marginTop: 2,
              marginLeft: 5,
              marginRight: 4,
              backgroundColor: "#8D8F97",
              borderRadius: 2,
              opacity: 0.45
            }}
          />
            <Text style={[global.courseHeaderSubTitle, {color: "blue"}]}>
              {t("lessonTopic:count", {
                topic: labels.topic,
                current: topic.order
              })}
            </Text>
          </View>
        </Animated.View>
      </View>
    </Animated.View>
  );
};

export default TopicTitle;


//In custom_code/index.js...

...

import TopicTitle from "./components/TopicTitle";
export const applyCustomCode = externalCodeSetup => {
 externalCodeSetup.learnTopicSingleScreenApi.setLearnTopicTitleComponent(props => <TopicTitle {...props} />)
}

# setPrevNextComponent(PrevNextComponentnullable)

You can use this to replace the previous and next buttons on the learn topic single screen if you want to change the default option which always displays the prev/next buttons.

Parameters:
Name Type Attributes Description
PrevNextComponent React.ComponentType.<LearnTopicPrevNextComponentProps> <nullable>
Example

Remove previous and next buttons if there is no previous and next objects. Otherwise, return the default previous and next buttons

//In custom_code/components/PrevNext.js

import React from "react";
import { Text, View, StyleSheet } from "react-native";
import AppTouchableOpacity from "@src/components/AppTouchableOpacity";
import Icon from "@src/components/Icon";
import { shadeColor } from "@src/utils";

export const onObjectClick = (
   object,
   onQuizClick,
   onTopicClick,
   onLessonClick
) => {
   if (!!!object) {
       return false;
   }
   switch (object.type) {
       case "quiz":
           onQuizClick(object.parentType, object.parent)(object);
           break;
       case "topic":
           onTopicClick(object, object.parent);
           break;
       case "lesson":
           onLessonClick(object);
           break;
   }
};

const PrevNext = ({
   global,
   colors,
   t,
	    prevObject,
   nextObject,
   courseId,
   onQuizClick,
   onLessonClick,
   onTopicClick,
   nextLockedAlert
}) => {

   if (!nextObject && !prevObject) {
       return null;
   }

   return (
       <View style={[global.row]}>
           <AppTouchableOpacity
               style={[
                   global.wrappedButton,
                   global.wrappedTextButton,
                   { marginRight: 4 }
               ]}
               onPress={() => {
                   if (prevObject !== "disabled") {
                       onObjectClick(prevObject, onQuizClick, onTopicClick, onLessonClick);
                   }
               }}
           >
               <View style={global.row}>
                   <View style={global.linkWithArrow}>
                       <Text
                           style={[
                               global.wrappedTextButtonLabel,
                               {
                                   color:
                                       !!!prevObject || prevObject === "disabled"
                                           ? shadeColor(colors.headerIconColor, 0.4)
                                           : colors.headerIconColor
                               }
                           ]}
                       >
                           {t("lesson:prevButtonText")}
                       </Text>
                   </View>
               </View>
           </AppTouchableOpacity>

           <AppTouchableOpacity
               style={[global.wrappedButton, global.wrappedTextButton]}
               onPress={() => {
                   if (nextObject !== "disabled") {
                       onObjectClick(nextObject, onQuizClick, onTopicClick, onLessonClick);
                   } else if (typeof nextLockedAlert === "function") {
                       nextLockedAlert();
                   }
               }}
           >
               <View style={global.row}>
                   <View style={global.linkWithArrow}>
                       <Text
                           style={[
                               global.wrappedTextButtonLabel,
                               {
                                   color:
                                       !!!nextObject || nextObject === "disabled"
                                           ? shadeColor(colors.headerIconColor, 0.4)
                                           : colors.headerIconColor
                               }
                           ]}
                       >
                           {t("lesson:nextButtonText")}
                       </Text>
                   </View>
               </View>
           </AppTouchableOpacity>
       </View>
   );
};

export default PrevNext;

//In custom_code/index.js...

...

import PrevNextComponent from './components/PrevNext';
export const applyCustomCode = externalCodeSetup => {
  externalCodeSetup.learnTopicSingleScreenApi.setPrevNextComponent((props) => <PrevNextComponent {...props} />);
}

# setShowMarkAsComplete(topic)

Use this to hide or show the mark as complete component.

Parameters:
Name Type Description
topic LearnTopicProps
Example
externalCodeSetup.learnTopicSingleScreenApi.setShowMarkAsComplete((topic) => false);

# setTransformTopicActionButtons(transformTopicActionButtons)

You can transform the default lesson action button by replacing it with your preferred action buttons. For example, you can add an inline button to the topic screen for marking topic completion.

Parameters:
Name Type Description
transformTopicActionButtons TransformTopicActionButtonsCallback
Example

Add more components for topic action

externalCodeSetup.learnTopicSingleScreenApi.setTransformTopicActionButtons((
  topicButton,
  showComplete,
  global,
  colors,
  topic,
  completing,
  labels,
  handleComplete) => {

  const Buttons =
    <View style={[global.row, { backgroundColor: "#fff" }]}>

      <View style={{ width: "45%", backgroundColor: "#fff", paddingHorizontal: 20, paddingVertical: 15 }}>
        <AppTouchableOpacity
          style={[
            global.completeTopicButtonW,
            { flex: 1, backgroundColor: colors.primaryButtonBg }
          ]}
          onPress={() => {
            //Do function...
          }}
        >
          <View style={global.row}>
            <View style={global.linkWithArrow}>
              <Text
                style={{ color: "#fff", fontWeight: "bold" }}
              >
                Questions?
              </Text>
            </View>
          </View>
        </AppTouchableOpacity>
      </View>
      <View style={{ width: "45%", marginLeft: "auto" }}>
        {topicButton}
      </View>
    </View>

  return Buttons;
})

# setVideoProgressionComponent(VideoProgressionComponent)

You can use this hook to customize the Video Progression component in the single topic screen. For example, you can use this to change the size of the video player or add a custom function when the video finishes playing on a topic

Parameters:
Name Type Description
VideoProgressionComponent React.ComponentType.<LearnTopicVideoProgressionComponentProps>
Example

Execute a custom callback when video has finished playing

...
import AppVideo from "@src/components/Video/AppVideo";

export const applyCustomCode = externalCodeSetup => {

  externalCodeSetup.learnTopicSingleScreenApi.setVideoProgressionComponent(props => {
    const {
      topicVideoStyle,
      controls,
      autoPlay,
      videoCallback,
      url,
      width,
      height,
      global,
      isNavActive,
      topic,
      videoWatched,
      setVideoWatched,
      onCompleteTopicClick
    } = props;

    const customCallback = settings => event => {

      if (event.nativeEvent.data === "ENDED") {

        if (!videoWatched)
          setVideoWatched();

        Alert.alert(
          "Video Complete",
          "You have finished watching the video. Do you want to mark the topic as complete?",
          [
            {
              text: "Cancel",
              onPress: () => console.log("Cancel Pressed"),
              style: "cancel"
            },
            { text: "OK", onPress: () => onCompleteTopicClick() }
          ]
        );
      }

    }

    return <View style={topicVideoStyle}>
      <AppVideo
        controls={controls}
        autoPlay={autoPlay}
        // videoCallback={videoCallback()}
        videoCallback={customCallback(topic.settings)}
        url={url}
        width={width}
        height={height}
        global={global}
        isNavActive={isNavActive}
      />
    </View>
  })
}