import * as React from "react";
/**
* @typedef {Object} PrevNextComponentProps
* @property {Function} onQuizClick Function to execute if previous or next button is a quiz
* @property {Function} onLessonClick Function to execute if previous or next button is a lesson
* @property {Function} onTopicClick Function to execute if previous or next button is a topic
* @property {Object} global App global style
* @property {Object} colors App colors
* @property {TranslationFunction} t
* @property {?Object} prevObject Information about previous lesson/topic/quiz
* @property {?Object} nextObject Information about next lesson/topic/quiz
* @property {Number} courseId Course id of lesson/topic/quiz
* @property {Function} nextLockedAlert Shows an alert with information that next object is locked
*/
/**
* @typedef {Object} PrevNextPlaceholderProps
* @property {Object} global App global style
*/
/**
* @typedef {Object} LessonHeaderProps
* @property {Object} global App global style
* @property {Object} colors App colors
* @property {LessonViewModel} lesson
* @property {Object} labels Learndash labels
* @property {TranslationFunction} t
* @property {Number} paddingTop Default padding top applied to component
* @property {Function} onQuizClick Function to execute if previous or next button is a quiz
* @property {Function} onLessonClick Function to execute if previous or next button is a lesson
* @property {Function} onTopicClick Function to execute if previous or next button is a topic
* @property {?Object} prevObject Information about previous lesson/topic/quiz
* @property {?Object} nextObject Information about next lesson/topic/quiz
* @property {Number} courseId Course id of lesson/topic/quiz
* @property {Function} nextLockedAlert Shows an alert with information that next object is locked
* @property {React.ComponentType} backToCourse Returns default back button component
* @property {Boolean} loading Returns `true` if screen is still loading
* @property {CourseViewModel} course
* @property {Boolean | React.ComponentType} renderTimer Returns `false` lesson doesn't have a timer set. Will return a component if timer for the lesson is set.
* @property {Function} onTimePassed Function which updates the seconds passed in the lesson screen container
* @property {NavigationService} navigation
* @property {Boolean} hidePrevNext Returns `true` if prev/next buttons should be hidden
* @property {Boolean | React.ComponentType} prevNext Returns `false` if hidePrevNext is `true`. Will return buttons which can navigate through previous and next screens if hidePrevNext is `false`
*/
/**
* @typedef {Object} LessonTitleComponentProps
* @property {LessonHeaderProps} LessonHeaderProps
*/
/**
* @typedef {Object} LessonScreenHeaderProps
* @property {LessonHeaderProps} LessonHeaderProps
* @property {Object} headerLeftStyle Default styling for left section of the header
* @property {Object} style Default styling of lesson header
* @property {Object} headerRightAuthWrapperProps Props which can be passed to an AuthWrapper
*/
/**
* @typedef {Function} TransformLessonActionButtonsCallback
* @property {React.ComponentType} lessonButton Lesson action button
* @property {Boolean} showComplete Returns `true` if "Mark Complete" button should be shown
* @property {Object} global App global style
* @property {Object} colors App colors
* @property {LessonViewModel} lesson
* @property {Boolean} completing Returns `true` if lesson is being completed
* @property {Object} labels Labels in the lesson
*/
/**
* @typedef {Object} LessonViewModel
* @property {Number} id Lesson id
* @property {String} title Lesson title
* @property {String} content Lesson content
* @property {Array} contentNative Blocks used in the lesson
* @property {Boolean} quizCompleted Returns `true` if quiz in the lesson has been completed
* @property {Number} quizCount Number of quizzes in the lesson
* @property {QuizViewModel} lessonQuizzes
* @property {Boolean} completed Returns `true` if lesson has been completed
* @property {Boolean} requireTimer Returns `true` if lesson requires timer
* @property {Number} timerRequiredTime Timer required time
* @property {Number} progression User's progress in the lesson
* @property {Boolean} hasAccess Returns `true` if logged in user has access to lesson
* @property {Boolean} hasContentAccess Returns `true` if logged in user has access to lesson's content
* @property {Number} topicsCount Number of topics in the lesson
* @property {String} videoUrl Url added in video progression of the lesson
* @property {Object} video Video details
*/
/**
* @typedef {Object} QuizViewModel
* @property {Number} id Quiz id
* @property {Object} title Quiz title
* @property {String} date Date when quiz was created
* @property {String} date_gmt Date when quiz was created
* @property {String} modified Date when quiz was last modified
* @property {String} modified_gmt Date when quiz was last modified
* @property {String} link Url to quiz
* @property {String} slug Slug of url to quiz
* @property {Number} author User id of author
* @property {Number} course Course id where quiz is located
* @property {Number} lesson Lesson id where quiz is located
* @property {Number} topic Topic id where quiz is located
* @property {Boolean} completed Returns `true` if quiz has been completed
* @property {Boolean} can_take_again Returns `true` if quiz can be taken again
*/
/**
* @typedef {Object} VideoProgressionComponentProps
* @property {Object} lessonVideoStyle Default styling applied to lesson video
* @property {Boolean} controls Returns `true` if controls should be displayed
* @property {Boolean} autoplay Returns `true` if auto play should be enabled
* @property {Function} videoCallback Helper function which can be called when the video has finished playing
* @property {String} url Video url
* @property {Number} width Player width
* @property {Number} height Player height
* @property {Object} global App global style
* @property {Boolean} isNavActive Returns `true` if screen is active
* @property {LessonViewModel} lesson
* @property {Boolean} showVideo Returns `true` if video should be shown
* @property {Boolean} videoWatched Returns `true` if video has already been watched
* @property {Function} setVideoWatched Helper function which dispatches an action and marks the video as watched
* @property {Function} completeLesson Helper function which dispatches an action to mark the lesson as complete
* @property {Function} onCompleteButtonClick Helper function which considers different conditions (such as if topics inside a lesson are already completed) before calling the `completeLesson` function
*/
/**
* @typedef {Object} AfterMaterialsComponentProps
* @property {Object} global App global style
* @property {Object} colors App colors
* @property {LessonViewModel} lesson
* @property {Object} labels Learndash labels
* @property {TranslationFunction} t
* @property {Function} onQuizClick Function to execute if previous or next button is a quiz
* @property {Function} onLessonClick Function to execute if previous or next button is a lesson
* @property {Function} onTopicClick Function to execute if previous or next button is a topic
* @property {?Object} prevObject Information about previous lesson/topic/quiz
* @property {?Object} nextObject Information about next lesson/topic/quiz
* @property {Function} nextLockedAlert Shows an alert with information that next object is locked
* @property {Boolean} loading Returns `true` if screen is still loading
* @property {CourseViewModel} course
* @property {NavigationService} navigation
* @property {String} materials Lesson materials
*/
/**
* @typedef {Object} LessonActionComponentProps
* @property {Object} global App global style
* @property {Object} colors App colors
* @property {LessonViewModel} lesson
* @property {Object} labels Learndash labels
* @property {TranslationFunction} t
* @property {Function} onCompleteButtonClick Helper function which considers different conditions (such as if topics inside a lesson are already completed) before calling the `completeLesson` function
* @property {Boolean} showComplete Returns `true` if "Mark Complete" button should be shown
* @property {Boolean} completing Returns `true` if lesson is being completed
* @property {Boolean} completeDisabled Returns `true` if "Mark Complete" button should be disabled
*/
/**
* @typedef {Function} TransformLessonViewModelCallback
* @property {LessonViewModel} viewModel
* @property {Object} lesson Lesson raw data from API
* @return {Object} New view model
*/
/**
* @class
* Lesson Screen Hooks.
* Instance name: lessonSingleScreenApi
You can use this hook to customize the lesson screen such as by adding a custom call to action button and other actions.
* @example
* externalCodeSetup.lessonSingleScreenApi.METHOD_NAME
*/
export class LessonSingleScreenHooksApi {
/**
* @deprecated
* Filters navigation onPress function that is used to navigate to Topic
*/
topicNavigationFilter = (onPress, navigation, topic, lessonId, courseId) =>
onPress;
/**
* @deprecated
*/
setTopicNavigationFilter = topicNavigationFilter => {
this.topicNavigationFilter = topicNavigationFilter;
};
PrevNextComponent = null;
/**
* You can use this to replace the previous and next buttons on the lessons single screen if you want to change the default option which always displays the prev/next buttons.
* @method
* @param {?React.ComponentType<PrevNextComponentProps>} PrevNextComponent
* @example <caption> Hide the previous and next buttons if you're only using one lesson in a course </caption>
*
* //In custom_code/components/PrevNext.js
*
* import React from "react";
* import PrevNext from "@src/components/Course/PrevNext";
*
* const PrevNextComponent = props => {
*
* const { onQuizClick,
* onLessonClick,
* onTopicClick,
* global,
* colors,
* t,
* prevObject,
* nextObject,
* courseId,
* nextLockedAlert } = props;
*
* if (! nextObject && ! prevObject){
* return null;
* }
*
* return (
* <PrevNext
* {...{ onQuizClick, onLessonClick, onTopicClick }}
* global={global}
* colors={colors}
* t={t}
* prevObject={prevObject}
* nextObject={nextObject}
* courseId={courseId}
* nextLockedAlert={nextLockedAlert}
* />
* );
* };
* export default PrevNextComponent;
*
* //In custom_code/index.js...
*
* ...
*
* import PrevNextComponent from './components/PrevNext';
* export const applyCustomCode = externalCodeSetup => {
* externalCodeSetup.lessonSingleScreenApi.setPrevNextComponent(props => <PrevNextComponent {...props} />)
* }
*
* @example <caption> Hide previous and next buttons </caption>
*
* ...
*
* export const applyCustomCode = externalCodeSetup => {
* externalCodeSetup.lessonSingleScreenApi.setPrevNextComponent(() => null)
* }
*
*/
setPrevNextComponent = PrevNextComponent => {
this.PrevNextComponent = PrevNextComponent;
};
PrevNextPlaceholder = null;
/**
* You can use this to replace the previous and next buttons' placeholders on the lessons single screen.
* The previous and next buttons' placeholders appear while the app is still loading the lesson.
* @method
* @param {?React.ComponentType<PrevNextPlaceholderProps>} PrevNextPlaceholder
* @example <caption> Change placeholder color </caption>
*
* externalCodeSetup.lessonSingleScreenApi.setPrevNextPlaceholder((props) => {
*
* const {global} = props;
*
* return <>
* <View
* style={[
* global.wrappedButton,
* global.wrappedTextButton,
* { marginRight: 4, width: 64, backgroundColor: "blue" }
* ]}
* />
* <View
* style={[
* global.wrappedButton,
* global.wrappedTextButton,
* { width: 65 , backgroundColor: "red"}
* ]}
* />
* </>
* })
*
* @example <caption> Hide the placeholder even while the screen is still loading </caption>
*
* externalCodeSetup.lessonSingleScreenApi.setPrevNextPlaceholder(() => null)
*
*/
setPrevNextPlaceholder = PrevNextPlaceholder => {
this.PrevNextPlaceholder = PrevNextPlaceholder;
};
transformLessonActionButtons = (
lessonButton,
showComplete,
global,
colors,
lesson,
completing,
labels
) => lessonButton;
/**
* You can transform the default lesson action button by replacing it with your preferred action buttons.
* @param {TransformLessonActionButtonsCallback} transformLessonActionButtons
* @method
* @example <caption> Add more components for lesson action </caption>
*
* externalCodeSetup.lessonSingleScreenApi.setTransformLessonActionButtons((
* lessonButton,
* showComplete,
* global,
* colors,
* lesson,
* completing,
* labels) => {
*
* const Buttons =
* <View style={[global.row, {backgroundColor: "#fff"}]}>
*
* <View style={{ width:"45%", backgroundColor: "#fff", paddingHorizontal: 20, paddingVertical: 15 }}>
* <AppTouchableOpacity
* style={[
* global.completeLessonButtonW,
* { 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" }}>
* {lessonButton}
* </View>
* </View>
*
* return Buttons;
* })
*/
setTransformLessonActionButtons = transformLessonActionButtons => {
this.transformLessonActionButtons = transformLessonActionButtons;
};
LessonTitleComponent = null;
/**
* You can use this to replace the lesson's title component.
* For example, you can use this to change the title's background or add an ellipsis feature to it.
* @method
* @param {React.ComponentType<LessonTitleComponentProps>} LessonTitleComponent
* @example <caption> Change component's background and add ellipsis to text </caption>
*
* //In custom_code/components/LessonTitle.js...
*
* import React from "react";
* import {View, Text} from "react-native";
* import Animated from "react-native-reanimated";
*
* const LessonTitle = (props) => {
*
* const {
* global,
* colors,
* paddingTop,
* lesson,
* t,
* labels
* } = props;
*
* const paddingBottom = 14;
*
* let backgroundColor = colors.bodyFrontBg;
* if (lesson.title.includes("Android")){
* backgroundColor = "red"
* }
*
* return (
* <Animated.View
* style={[
* {
* backgroundColor: backgroundColor,
* 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
* }
* ]}
* >
* <Animated.View
* style={{
* flex: 1,
* paddingHorizontal: 20
* }}
* >
* <Animated.Text
* style={[
* global.courseHeaderTitle,
* {marginBottom: 5}
* ]}
* numberOfLines={1} //Adds ellipsis to lesson title
* >
* {lesson.title}
* </Animated.Text>
* <Text style={global.courseHeaderSubTitle}>
* {t("lesson:count", {
* label: labels.lesson,
* current: lesson.order,
* total: lesson.total
* })}
* </Text>
* </Animated.View>
* </View>
* </Animated.View>
* );
* };
*
* export default LessonTitle;
*
* //In custom_code/index.js...
*
* ...
* import LessonTitle from "./components/LessonTitle"
* export const applyCustomCode = externalCodeSetup => {
* externalCodeSetup.lessonSingleScreenApi.setLessonTitleComponent(props => <LessonTitle {...props} />)
* }
*
* @example <caption> Add screen header components to lesson title </caption>
*
* // In custom_code/components/LessonTitle.js...
* import React from "react";
* import { useSelector } from "react-redux";
* import { View, Text, StyleSheet } from "react-native";
* import Animated from "react-native-reanimated";
* import PrevNext from "@src/components/Course/PrevNext";
* import Icon from "@src/components/Icon";
* import TimeCounter from "@src/components/TimeCounterAutoPause";
*
* const LessonTitle = (props) => {
*
* const {
* title,
* global,
* colors,
* paddingTop,
* lesson,
* t,
* labels,
* onQuizClick,
* onLessonClick,
* onTopicClick,
* prevObject,
* nextObject,
* courseId,
* nextLockedAlert,
* backToCourse,
* course,
* loading,
* renderTimer,
* onTimePassed,
* navigation
* } = props;
*
* const paddingBottom = 14;
*
* const renderDefaultTimer = false
*
* const isLessonCompleting = useSelector(state => state.singleLesson.completing == lesson.id);
*
* const CustomTimer = () => {
*
* if (loading || !lesson.requireTimer || isLessonCompleting)
* return null;
*
* return <View
* style={{
* flexDirection: "row",
* alignItems: "center"
* }}
* >
* <Text>My Custom Timer</Text>
* <Icon
* icon={require("@src/assets/img/stopwatch.png")}
* webIcon={"IconArrowBack"}
* tintColor={colors.textIconColor}
* styles={{
* marginRight: 6,
* height: 20,
* width: 20
* }}
* />
* <TimeCounter
* paused={!navigation.isActive}
* onTimePassed={onTimePassed}
* initialSeconds={0}
* textProps={{ style: global.timer }}
* />
* </View>
* }
*
* return (
* <Animated.View
* style={[
* {
* backgroundColor: colors.bodyFrontBg,
* width: "100%",
* shadowOffset: { width: 0, height: 1 },
* shadowRadius: 1,
* shadowColor: "#000",
* shadowOpacity: 0.05,
* marginTop: 50
* }
* ]}
* >
* <View
* style={[
* global.row,
* {
* justifyContent: "space-between",
* alignItems: "flex-start",
* paddingTop,
* paddingBottom
* }
* ]}
* >
* <Animated.View
* style={{
* flex: 1,
* paddingHorizontal: 20
* }}
* >
* //ScreenHeader components
* <View style={{ flexDirection: "row", marginLeft: -20 }}>
* {backToCourse}
*
* <PrevNext
* {...{ onQuizClick, onLessonClick, onTopicClick }}
* global={global}
* colors={colors}
* t={t}
* prevObject={prevObject}
* nextObject={nextObject}
* courseId={courseId}
* nextLockedAlert={nextLockedAlert}
* />
*
* {renderDefaultTimer ? renderTimer : <CustomTimer />}
*
* </View>
* //End ScreenHeader components
*
* <Animated.Text
* style={[
* global.courseHeaderTitle,
* { marginBottom: 5 }
* ]}
* numberOfLines={1} //Adds ellipsis to lesson title
* >
* {lesson.title}
* </Animated.Text>
*
* <Text style={global.courseHeaderSubTitle}>
* {t("lesson:count", {
* label: labels.lesson,
* current: lesson.order,
* total: lesson.total
* })}
* </Text>
* </Animated.View>
* </View>
* </Animated.View>
* );
* };
*
* export default LessonTitle;
*
* //In custom_code/index.js...
*
* ...
* import LessonTitle from "./components/LessonTitle"
* export const applyCustomCode = externalCodeSetup => {
* externalCodeSetup.lessonSingleScreenApi.setLessonTitleComponent(props => <LessonTitle {...props} />)
* }
*/
setLessonTitleComponent = LessonTitleComponent => {
this.LessonTitleComponent = LessonTitleComponent;
};
LessonScreenHeader = null;
/**
* You can use this hook to customize the header of the Lesson Single Screen which by default, contains the back-to-course button and the previous/next buttons.
* @method
* @param {React.ComponentType<LessonScreenHeaderProps>} LessonScreenHeader
* @example
*
* //In custom_code/components/LessonScreenHeader.js...
*
* import React from "react";
* import {View} 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
* }) => {
* 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%"
* }
* ]}
* >
* <View style={[global.headerButtonLeft, headerLeftStyle]}>
* {backToCourse}
* </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 LessonScreenHeader from "./components/LessonScreenHeader";
* export const applyCustomCode = externalCodeSetup => {
* externalCodeSetup.lessonSingleScreenApi.setLessonScreenHeader(props => <LessonScreenHeader {...props}/>)
* }
*/
setLessonScreenHeader = LessonScreenHeader => {
this.LessonScreenHeader = LessonScreenHeader;
};
VideoProgressionComponent = null;
/**
* You can use this hook to customize the Video Progression component in the single lesson 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 lesson.
* @method
* @param {React.ComponentType<VideoProgressionComponentProps>} VideoProgressionComponent
* @example <caption> Execute a custom callback when video has finished playing </caption>
*
* ...
* import AppVideo from "@src/components/Video/AppVideo";
*
* export const applyCustomCode = externalCodeSetup => {
*
* externalCodeSetup.lessonSingleScreenApi.setVideoProgressionComponent(props => {
* const {
* lessonVideoStyle,
* controls,
* autoPlay,
* videoCallback,
* url,
* width,
* height,
* global,
* isNavActive,
* lesson,
* videoWatched,
* setVideoWatched,
* onCompleteButtonClick
* } = 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 lesson as complete?",
* [
* {
* text: "Cancel",
* onPress: () => console.log("Cancel Pressed"),
* style: "cancel"
* },
* { text: "OK", onPress: () => onCompleteButtonClick() }
* ]
* );
* }
*
* }
*
* return <View style={lessonVideoStyle}>
* <Text>Please finish watching the video below to proceed...</Text>
* <AppVideo
* controls={controls}
* autoPlay={autoPlay}
* // videoCallback={videoCallback()}
* videoCallback={customCallback(lesson.settings)}
* url={url}
* width={width}
* height={height}
* global={global}
* isNavActive={isNavActive}
* />
* </View>
* })
* }
*
*/
setVideoProgressionComponent = VideoProgressionComponent => {
this.VideoProgressionComponent = VideoProgressionComponent;
};
AfterMaterialsComponent = null;
/**
* You can use this hook to add a component at the bottom of the lesson single screen just after the component that displays the materials.
* @method
* @param {React.ComponentType<AfterMaterialsComponentProps>} AfterMaterialsComponent
* @example
*
* //In custom_code/components/LessonBottomComponent.js...
*
* import React from "react";
* import { View, Text, TouchableOpacity } from "react-native";
* const LessonBottomComponent = props => {
*
* const {
* colors,
* course,
* 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 LessonBottomComponent;
*
* //In custom_code/index.js...
*
* ...
*
* import LessonBottomComponent from "./components/LessonBottomComponent";
* export const applyCustomCode = externalCodeSetup => {
* externalCodeSetup.lessonSingleScreenApi.setAfterMaterialsComponent(props => <LessonBottomComponent {...props}/>)
* }
*/
setAfterMaterialsComponent = AfterMaterialsComponent => {
this.AfterMaterialsComponent = AfterMaterialsComponent;
};
LessonActionComponent = null;
/**
* 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.
* @method
* @param {React.ComponentType<LessonActionComponentProps>} LessonActionComponent
* @example <caption> Add a "Completing..." text when marking the lesson complete </caption>
*
* //In custom_code/components/LessonActionComponent.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 LessonActionComponent = ({
* showComplete,
* global,
* colors,
* t,
* lesson,
* onCompleteButtonClick,
* completing,
* completeDisabled,
* labels
* }) => (<AuthWrapper actionOnGuestLogin={"hide"}>
* {showComplete && (
* <View
* style={[
* global.row,
* {
* backgroundColor: colors.bodyFrontBg,
* borderTopColor: colors.borderColor
* },
* global.lessonActionButtonContainer
* ]}
* >
* <AppTouchableOpacity
* style={[
* { flex: 1 },
* {
* opacity: !lesson.completed && completeDisabled ? 0.5 : 1,
* backgroundColor: !lesson.completed
* ? colors.primaryButtonBg
* : colors.bodyFrontBg
* },
* global.completeLessonButtonW
* ]}
* disabled={lesson.completed || completeDisabled}
* onPress={onCompleteButtonClick}
* >
* <View style={global.row}>
* <View style={global.linkWithArrow}>
* {!lesson.completed ? (
* completing && (
* <>
* <Text style={{color: "#fff"}}>Completing...</Text>
* <ActivityIndicator
* animating={true}
* color={colors.primaryButtonColor}
* size="small"
* style={global.lessonButtonLoadingIcon}
* />
* </>
* )
* ) : (
* <Icon
* webIcon={""}
* icon={require("@src/assets/img/completed-course.png")}
* styles={global.lessonActionCompleteIcon}
* />
* )}
* <Text
* style={[
* {
* marginLeft: 10,
* color: !lesson.completed
* ? colors.primaryButtonColor
* : isColorDark(colors.bodyFrontBg)
* ? "white"
* : "black"
* },
* !lesson.completed
* ? global.completeLessonButton
* : global.completeButton
* ]}
* >
* {t(
* lesson.completed
* ? "lesson:completed"
* : "lesson:completeLesson",
* { label: labels.lesson.toLowerCase() }
* )}
* </Text>
* </View>
* </View>
* </AppTouchableOpacity>
* </View>
* )}
* </AuthWrapper>)
*
* export default LessonActionComponent;
*
* //In custom_code/index.js...
*
* ...
*
* import LessonActionComponent from "./components/LessonActionComponent";
* export const applyCustomCode = (externalCodeSetup: any) => {
* externalCodeSetup.lessonSingleScreenApi.setLessonActionComponent(props => <LessonActionComponent {...props} />)
* }
*
*/
setLessonActionComponent = LessonActionComponent => {
this.LessonActionComponent = LessonActionComponent;
};
lessonViewModelFilter = (viewModel, lesson) => viewModel;
/**
* Sets the callback function that can change an existing lesson view model object.
* @method
* @param {TransformLessonViewModelCallback} lessonViewModelFilter
* @example <caption>Remove the native blocks in a lesson</caption>
* externalCodeSetup.lessonSingleScreenApi.setLessonViewModelFilter((viewModel, lesson) => {
* return {
* ...viewModel,
* contentNative: []
* }
* })
*/
setLessonViewModelFilter = lessonViewModelFilter => {
this.lessonViewModelFilter = lessonViewModelFilter;
};
}
Source