/**
* @typedef {Object} QuizDetailVM
* @property {Boolean} showCategoryScore Returns `true` if category score should be shown
* @property {Boolean} hideResultQuizTime Returns `true` if result quiz time should be hidden
* @property {Boolean} hideResultPoints Returns `true` if result points should be hidden
* @property {Boolean} showAverageResult Returns `true` if average result should be shown
* @property {Boolean} btnViewQuestionHidden Returns `true` if review button should be hidden
*/
/**
* @typedef {Object} ResultDetailsProps
* @property {Object} result Quiz result details
* @property {QuizDetailVM} quizVM
* @property {Object} global App global style
* @property {Object} colors App colors
* @property {TranslationFunction} t
*/
/**
* @typedef {Object} DetailCategoryTitleProps
* @property {ResultDetailsProps}
*/
/**
* @typedef {Object} ResultMessageProps
* @property {ResultDetailsProps}
*/
/**
* @typedef {Object} CategoryScoreComponentProps
* @property {ResultDetailsProps}
*/
/**
* @typedef {Object} ResultPointsComponentProps
* @property {ResultDetailsProps}
*/
/**
* @typedef {Object} ResultIconComponentProps
* @property {ResultDetailsProps}
*/
/**
* @typedef {Object} RecapMessageProps
* @property {ResultDetailsProps}
*/
/**
* @typedef {Object} ReviewQuizButtonProps
* @property {ResultDetailsProps}
* @property {Number} bottomSafeArea
* @property {Function} onReviewClick Helper function that navigates to Quiz Review screen
* @property {Object} labels Learndash labels
*/
/**
* @class
* Quiz Detail Screen Hooks.
* Instance name: quizDetailApi
You can use these hooks to customize the quiz detail screen components in your app such as customizing the result message, recap message and so on.
* @example
* externalCodeSetup.quizDetailApi.METHOD_NAME
*/
export class QuizDetailApi {
DetailCategoryTitle = null;
/**
* You can use this to customize the component that displays the "Category" title.
* For example, you can change the styling of the text component.
* @method
* @param {React.ComponentType<DetailCategoryTitleProps>} DetailCategoryTitle
* @example
*
* externalCodeSetup.quizDetailApi.setDetailCategoryTitle(({
* result,
* quizVM,
* global,
* t
* }) =>
* Array.isArray(result.cats) &&
* result.cats.length &&
* quizVM.showCategoryScore && (
* <Text style={global.resultsSubTitle}>
* {t("quiz:quizCategories")}
* </Text>
* )
* )
*/
setDetailCategoryTitle = DetailCategoryTitle => {
this.DetailCategoryTitle = DetailCategoryTitle;
};
CategoryScoreComponent = null;
/**
* You can use this to customize the category scores component.
* @method
* @param {React.ComponentType<CategoryScoreComponentProps>} CategoryScoreComponent
* @example
*
* ...
*
* import { View, Text, StyleSheet } from "react-native"
* import {
* FontWeights
* } from "@src/styles/global";
*
* export const applyCustomCode = (externalCodeSetup: any) => {
*
* externalCodeSetup.quizDetailApi.setCategoryScoreComponent(({
* result,
* quizVM,
* global,
* colors
* }) => {
*
* const firstC = 6;
* const secondC = 1.6;
* const thirdC = 2.4;
*
* return Array.isArray(result.cats) &&
* result.cats.length &&
* quizVM.showCategoryScore && (
* <View
* style={[
* {
* marginTop: 15,
* borderBottomWidth: StyleSheet.hairlineWidth,
* borderBottomColor: colors.borderColor
* }
* ]}
* >
* {result.cats.map((item, index) => {
* return (
* <View key={index} style={[global.row, { marginBottom: 15 }]}>
* <Text
* style={{
* ...global.textAlt,
* fontWeight: FontWeights.medium,
* flex: firstC
* }}
* >
* {item.name}
* </Text>
* <Text
* style={[
* global.textAlt,
* {
* fontWeight: FontWeights.medium,
* marginLeft: "auto",
* color: "#8D8F97",
* flex: secondC
* }
* ]}
* >
* {item.result.toFixed(0)}%
* </Text>
* <Text
* style={[
* global.textAlt,
* {
* fontWeight: FontWeights.medium,
* marginLeft: "auto",
* color: "#8D8F97",
* flex: thirdC
* }
* ]}
* />
* </View>
* );
* })}
* </View>
* )
* })
* }
*/
setCategoryScoreComponent = CategoryScoreComponent => {
this.CategoryScoreComponent = CategoryScoreComponent;
};
ResultPointsComponent = null;
/**
* You can use this to customize the points component.
* @method
* @param {React.ComponentType<ResultPointsComponentProps>} ResultPointsComponent
* @example
*
* ...
*
*import { View, Text } from "react-native"
*import {
* FontWeights
*} from "@src/styles/global";
*
*export const applyCustomCode = (externalCodeSetup: any) => {
*
* externalCodeSetup.quizDetailApi.setResultPointsComponent(({
* quizVM,
* global,
* colors,
* t,
* result
* }) => {
*
* const firstC = 6;
* const secondC = 1.6;
* const thirdC = 2.4;
*
* return !quizVM.hideResultPoints && (
* <View style={[{ marginTop: 25 }]}>
* <View style={[global.row, { marginBottom: 15 }]}>
* <Text
* style={{
* ...global.text,
* fontWeight: FontWeights.medium,
* flex: firstC
* }}
* >
* {t("quiz:quizYourScore")}
* </Text>
* <Text
* style={[
* global.textAlt,
* {
* color: colors.descTextColor,
* flex: secondC,
* fontSize: 16,
* fontWeight: FontWeights.medium
* }
* ]}
* >
* {Math.round((result.result || 0) * 100) / 100}%
* </Text>
* <Text
* style={[
* global.textAlt,
* {
* color: colors.descTextColor,
* flex: thirdC,
* textAlign: "right",
* fontSize: 16,
* fontWeight: FontWeights.medium
* }
* ]}
* >
* {t("quiz:pointsCount", {
* count: parseInt(result.awarded_points) || 0
* })}
* </Text>
* </View>
* <View style={[global.row, {marginBottom: 15}]}>
* <Text
* style={{
* ...global.text,
* fontWeight: FontWeights.medium,
* flex: firstC
* }}
* >
* {t("quiz:passingScore")}
* </Text>
* <Text
* style={[
* global.textAlt,
* {
* color: colors.descTextColor,
* flex: secondC,
* fontSize: 16,
* fontWeight: FontWeights.medium
* }
* ]}
* >
* {Math.round(result.passing_percentage * 100) / 100}%
* </Text>
* <Text
* style={[
* global.textAlt,
* {
* color: colors.descTextColor,
* flex: thirdC,
* textAlign: "right",
* fontSize: 16,
* fontWeight: FontWeights.medium
* }
* ]}
* >
* {t("quiz:pointsCount", {
* count:
* parseInt(
* Math.round(
* result.possible_points * result.passing_percentage
* ) / 100
* ) || 0
* })}
* </Text>
* </View>
* </View>
* )
* })
* }
*/
setResultPointsComponent = ResultPointsComponent => {
this.ResultPointsComponent = ResultPointsComponent;
};
ResultIconComponent = null;
/**
* You can use this to change the icon displayed in the screen.
* For example, you can use your own image instead of the default success and fail images.
* @method
* @param {React.ComponentType<ResultIconComponentProps>} ResultIconComponent
* @example
*
* ...
*
* import Icon from "@src/components/Icon";
* import {SUCCESS_COLOR, WARNING_COLOR} from "@src/styles/global";
*
* export const applyCustomCode = (externalCodeSetup: any) => {
* externalCodeSetup.quizDetailApi.setResultIconComponent(({result}) => (
* <View
* style={{
* marginTop: 15,
* justifyContent: "center",
* alignItems: "center"
* }}
* >
* <View
* style={{
* paddingLeft: 40,
* paddingRight: 40,
* alignItems: "center"
* }}
* >
* {result.is_pass ? (
* <Icon
* icon={{fontIconName: "check", weight: 200}}
* tintColor={SUCCESS_COLOR}
* style={{
* width: 50,
* height: 50,
* marginTop: 25
* }}
* />
* ) : (
* <Icon
* icon={{fontIconName: "times", weight: 200}}
* tintColor={WARNING_COLOR}
* style={{
* width: 50,
* height: 50,
* marginTop: 25
* }}
* />
* )}
* </View>
* </View>
* ));
* }
*/
setResultIconComponent = ResultIconComponent => {
this.ResultIconComponent = ResultIconComponent;
};
ResultMessage = null;
/**
* You can use this to customize the result message displayed.
* @method
* @param {React.ComponentType<ResultMessageProps>} ResultMessage
* @example <caption> Implement deep linking to the result message </caption>
*
* //In custom_code/ResultMessage.js...
*
* import React from "react";
* import {View} from "react-native";
* import HTML from "react-native-render-html";
* import {withNavigation} from "@src/components/hocs/withNavigation";
* import withDeeplinkClickHandler from "../../src/components/hocs/withDeeplinkClickHandler";
* import { compose } from "recompose";
*
* const ResultMessage = ({
* result,
* global,
* colors,
* attemptDeepLink
* }) => <View
* style={{
* width: "100%",
* marginTop: 16,
* paddingHorizontal: 16
* }}
* >
* {!!result.message && (
* <HTML
* onLinkPress={attemptDeepLink(false)}
* contentStyle={{marginHorizontal: 20}}
* html={`<center>${result.message}</center>`}
* baseFontStyle={global.text}
* tagsStyles={{
* center: {
* alignItems: "center"
* },
* h1: {
* marginBottom: 10
* },
* h2: {
* marginBottom: 10
* },
* h3: {
* marginBottom: 10
* },
* h4: {
* marginBottom: 10
* },
* h5: {
* marginBottom: 10
* },
* h6: {
* marginBottom: 10
* },
* p: {
* marginTop: 0,
* marginBottom: 10
* },
* a: {
* color: colors.linkColor,
* textDecorationLine: "none"
* }
* }}
* />
* )}
* </View>
*
* export default compose(
* withNavigation,
* withDeeplinkClickHandler
* )(ResultMessage)
*
* //In custom_code/index.js...
*
* import ResultMessage from "./components/ResultMessage";
* export const applyCustomCode = (externalCodeSetup: any) => {
* externalCodeSetup.quizDetailApi.setResultMessage(props => <ResultMessage {...props} /> );
* }
*
*/
setResultMessage = ResultMessage => {
this.ResultMessage = ResultMessage;
};
RecapMessage = null;
/**
* You can use this to customize the recap message text below the result message.
* @method
* @param {React.ComponentType<RecapMessageProps>} RecapMessage
* @example
*
* ...
*
* externalCodeSetup.quizDetailApi.setRecapMessage(({ quizVM, global, colors, t }) => (
* !quizVM.btnViewQuestionHidden && (
* <Text
* style={[
* global.textAlt,
* {
* marginHorizontal: 20,
* color: colors.descTextColor,
* textAlign: "center",
* marginBottom: 36
* }
* ]}
* >
* {t("quiz:recap")}
* </Text>
* )
* ))
*/
setRecapMessage = RecapMessage => {
this.RecapMessage = RecapMessage;
};
ReviewQuizButton = null;
/**
* You can use this to customize the ReviewQuizButton component which by default, navigates you to the QuizReview screen.
* @method
* @param {React.ComponentType<ReviewQuizButtonProps>} ReviewQuizButton
* @example
*
* ...
*
* import AppButton from "@src/components/AppButton";
*
* export const applyCustomCode = (externalCodeSetup: any) => {
* externalCodeSetup.quizDetailApi.setReviewQuizButton(({
* quizVM,
* global,
* colors,
* t,
* labels,
* onReviewClick,
* bottomSafeArea
* }) => !quizVM.btnViewQuestionHidden && (
* <View
* style={[
* {
* paddingTop: 16,
* paddingHorizontal: 20,
* backgroundColor: "#fff",
* borderTopWidth: StyleSheet.hairlineWidth,
* borderTopColor: "#C6C6C8",
* paddingBottom: bottomSafeArea
* }
* ]}
* >
* <AppButton
* style={[
* { backgroundColor: colors.secondaryButtonBg, height: 40 }
* ]}
* onPress={onReviewClick}
* labelStyle={{
* ...global.quizReviewButtonLabel,
* color: colors.secondaryButtonColor
* }}
* label={t("quiz:reviewQuiz", { quiz: labels.quiz })}
* global={global}
* loading={false}
* />
* </View>
* ))
* }
*
*/
setReviewQuizButton = ReviewQuizButton => {
this.ReviewQuizButton = ReviewQuizButton;
};
}
Source