# 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 |
LearnTopicAfterContentRendererProps |
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}/>)
}
# setAssignmentItemComment(AssignmentItemComment)
You can use this to customize the AssignmentItemComment button.
Parameters:
Name | Type | Description |
---|---|---|
AssignmentItemComment |
React.ComponentType.<AssignmentItemCommentProps> |
Example
...
import AssignmentCommentButton from "@src/components/Course/Assignment/AssignmentCommentButton";
export const applyCustomCode = (externalCodeSetup) => {
externalCodeSetup.learnTopicSingleScreenApi.setAssignmentItemComment(
({
pressHandler,
tintColor,
containerStyle,
count,
size,
global,
lightMode
}) => (
<AssignmentCommentButton
{...{
pressHandler,
tintColor,
containerStyle,
count,
size,
global,
lightMode
}}
/>
)
);
}
# setAssignmentItemDownload(AssignmentItemDownload)
You can use this to customize the AssignmentItemDownload button. For example, you can change the icon and add a confirmation modal before allowing the user to download the assignment file.
Parameters:
Name | Type | Description |
---|---|---|
AssignmentItemDownload |
React.ComponentType.<AssignmentItemDownloadProps> |
Example
...
import AssignmentDownloadButton from "@src/components/Course/Assignment/AssignmentDownloadButton";
export const applyCustomCode = (externalCodeSetup) => {
externalCodeSetup.learnTopicSingleScreenApi.setAssignmentItemDownload(
({pressHandler, tintColor, containerStyle, size, global, lightMode}) => (
<AssignmentDownloadButton
{...{
pressHandler,
tintColor,
containerStyle,
size,
global,
lightMode
}}
/>
)
);
}
# setAssignmentItemDownloadProgress(AssignmentItemDownloadProgress)
You can use this to customize the progress indicator which is showed when the assignment item is being downloaded.
Parameters:
Name | Type | Description |
---|---|---|
AssignmentItemDownloadProgress |
React.ComponentType.<AssignmentItemDownloadProgressProps> |
Example
...
import AssignmentDownloadProgress from "@src/components/Course/Assignment/AssignmentDownloadProgress";
export const applyCustomCode = (externalCodeSetup) => {
externalCodeSetup.learnTopicSingleScreenApi.setAssignmentItemDownloadProgress(
({progress, unfilledColor, tintColor}) => (
<AssignmentDownloadProgress
{...{
progress,
unfilledColor,
tintColor
}}
/>
)
);
}
# setAssignmentItemIcon(AssignmentItemIcon)
You can use this to change the icon beside the assignment title. For example, you can use this to remove or modify the default icon.
Parameters:
Name | Type | Description |
---|---|---|
AssignmentItemIcon |
React.ComponentType.<AssignmentItemIconProps> |
Example
...
import Icon from "@src/components/Icon";
export const applyCustomCode = (externalCodeSetup) => {
externalCodeSetup.learnTopicSingleScreenApi.setAssignmentItemIcon(
({icon, styles}) => <Icon icon={icon} styles={styles} />
);
}
# setAssignmentItemStatus(AssignmentItemStatus)
You can use this to customize the AssignmentItemStatus component.
Parameters:
Name | Type | Description |
---|---|---|
AssignmentItemStatus |
React.ComponentType.<AssignmentItemStatusProps> |
Example
...
import {BubbleIcon} from "@src/components/BubbleIcon";
export const applyCustomCode = (externalCodeSetup) => {
externalCodeSetup.learnTopicSingleScreenApi.setAssignmentItemStatus(
({global, text, containerStyle, textStyle}) => (
<BubbleIcon
{...{
global,
text,
containerStyle,
textStyle
}}
/>
)
);
}
# setAssignmentItemTitle(AssignmentItemTitle)
You can use this to customize the AssignmentItemTitle component. For example, you can use this to change the font color or size of the title.
Parameters:
Name | Type | Description |
---|---|---|
AssignmentItemTitle |
React.ComponentType.<AssignmentItemTitleProps> |
Example
...
export const applyCustomCode = (externalCodeSetup) => {
externalCodeSetup.learnTopicSingleScreenApi.setAssignmentItemTitle(({
title,
style
}) => <Text style={style}>{title}</Text>)
}
# setAssignmentsHeader(AssignmentsHeader)
You can use this hook to customize the assignments title and the component that displays the total approved assignments.
Parameters:
Name | Type | Description |
---|---|---|
AssignmentsHeader |
React.ComponentType.<AssignmentsHeaderProps> |
Example
...
export const applyCustomCode = (externalCodeSetup) => {
externalCodeSetup.learnTopicSingleScreenApi.setAssignmentsHeader(
({global, t, totalAssignments, approved}) => (
<View style={{...global.row, flex: 1, marginBottom: 15}}>
<Text style={[global.assignmentHeading, {flex: 1}]}>
{t("assignment:heading")}
</Text>
{totalAssignments !== 0 && (
<Text style={[global.assignmentDesc]}>
{t("assignment:approvedOutOfTotal", {
total: totalAssignments,
approved
})}
</Text>
)}
</View>
)
);
}
# 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={{fontIconName: "check", weight: 200}}
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} />)
}
# setLearnTopicMaterialsSectionTitle(LearnTopicMaterialsSectionTitle)
You can use this hook to customize the component that displays the "Materials" text.
Parameters:
Name | Type | Description |
---|---|---|
LearnTopicMaterialsSectionTitle |
React.ComponentType.<LearnTopicMaterialsSectionTitleProps> |
Example
...
export const applyCustomCode = (externalCodeSetup) => {
externalCodeSetup.learnTopicSingleScreenApi.setLearnTopicMaterialsSectionTitle(
({global, t}) => (
<Text
style={{
...global.courseRoundBoxTitleAbove,
marginBottom: 20
}}
>
{t("lesson:materials")}
</Text>
)
);
}
# 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.setLearnTopicScreenHeader(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.<LearnTopicHeaderProps> |
Example
//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} />)
}
# setLearnTopicViewModelFilter(learnTopicViewModelFilter)
Sets the callback function that can change an existing learn topic view model object.
Parameters:
Name | Type | Description |
---|---|---|
learnTopicViewModelFilter |
TransformLearnTopicViewModelCallback |
Example
externalCodeSetup.learnTopicSingleScreenApi.setLearnTopicViewModelFilter((viewModel, topic) => {
return {
...viewModel,
contentNative: []
}
})
# setMaterialsComponent(MaterialsComponent)
You can use this to customize the component that displays the materials of the topic.
Parameters:
Name | Type | Description |
---|---|---|
MaterialsComponent |
React.ComponentType.<MaterialsComponentProps> |
Example
...
import {
Dimensions,
} from "react-native";
import HTML from "react-native-render-html";
import {RenderListPrefix} from "@src/components/Course/CourseMaterials"
const ent = require("ent");
const DEVICE_WIDTH = Dimensions.get("window").width;
export const applyCustomCode = (externalCodeSetup) => {
externalCodeSetup.learnTopicSingleScreenApi.setMaterialsComponent((props) => {
const {
tagsStyles,
materialsStyles,
baseFontStyle,
materials,
onLinkPress,
global,
colors
} = props;
return (
<HTML
tagsStyles={{...tagsStyles, ...materialsStyles}}
baseFontStyle={baseFontStyle(15)}
html={ent.decode(materials)}
imagesMaxWidth={DEVICE_WIDTH - 32}
onLinkPress={onLinkPress}
listsPrefixesRenderers={{
ul: (attrib, children, styles, passProps) => (
<RenderListPrefix
parent={"ul"}
colors={colors}
global={global}
passProps={passProps}
/>
),
ol: (attrib, children, styles, passProps) => (
<RenderListPrefix
parent={"ol"}
colors={colors}
global={global}
passProps={passProps}
/>
)
}}
/>
)
});
}
# setOfflineComponent(OfflineComponent)
You can use this hook to customize the component that displays a "This content is not available offline" message if a webview is used for rendering the topic content while the device is offline.
Parameters:
Name | Type | Description |
---|---|---|
OfflineComponent |
React.ComponentType.<LearnTopicOfflineComponentProps> |
Example
...
import EmptyList from "@src/components/EmptyList";
export const applyCustomCode = (externalCodeSetup) => {
externalCodeSetup.learnTopicSingleScreenApi.setOfflineComponent(
({containerStyle, t, global, emptyListStyle}) => (
<View style={containerStyle}>
<EmptyList
emptyText={{
title: t("common:contentOfflineMessage"),
icon: {fontIconName: "wifi-slash", weight: 400}
}}
global={global}
style={emptyListStyle}
/>
</View>
)
);
}
# setPrevNextComponent(PrevNextComponent)
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 | Description |
---|---|---|
PrevNextComponent |
React.ComponentType.<LearnTopicPrevNextComponentProps> |
Example
//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(showMarkAsComplete)
Use this to hide or show the mark as complete component.
Parameters:
Name | Type | Description |
---|---|---|
showMarkAsComplete |
showMarkAsCompleteProps |
Example
externalCodeSetup.learnTopicSingleScreenApi.setShowMarkAsComplete((topic) => false);
# setTransformTopicActionButtons(transformTopicActionButtons)
You can transform the default learn topic 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
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
...
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>
})
}
# setWebViewContentComponent(WebViewContentComponent)
You can use this hook to replace the webview being used in the topic content. For example, you can choose to replace it with the default react-native webview.
Parameters:
Name | Type | Description |
---|---|---|
WebViewContentComponent |
React.ComponentType.<LearnTopicWebViewContentComponentProps> |
Example
...
import WebViewWithMore from "@src/components/WebViewWithMore";
export const applyCustomCode = (externalCodeSetup) => {
externalCodeSetup.learnTopicSingleScreenApi.setWebViewContentComponent(
({
online,
t,
onShouldStartLoadWithRequest,
height,
source,
global,
colors,
ModalHeaderComponent
}) => (
<WebViewWithMore
online={online}
t={t}
onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
height={height}
source={source}
global={global}
colors={colors}
ModalHeaderComponent={ModalHeaderComponent}
/>
)
);
}