import * as React from "react";
import {Image} from "react-native";
/**
* @typedef {Object} BackButtonComponentProps
* @property {NavigationService} navigation
* @property {String} headerColor
* @property {RNStyleValue} styles Back button default styling
* @property {Boolean|undefined} delay Returns `true` for default setting is to delay rendering
* @property {Boolean|undefined} withUnderlay Returns `true` if button should be rendered with an underlay
* @property {String} text Default text
* @property {Record<any,any>} textStyle Default text style
* @property {Number} textMaxWidth Defaul text max width
* @property {Record<any,any>} colors App colors
* @property {Function} afterAction Action after the screen has navigated to the previous screen
* @property {Function|undefined} handlePressParam Default behavior when button is pressed
* @property {Object|undefined} containerStyle Container style
* @property {String|undefined} fontIconName Font name of icon
* @property {Number|undefined} fontIconWeight Font weight of icon
*/
/**
* @typedef {Object} ProgressListItemComponentProps
* @property {Object} item
* @property {Object} global App global style
* @property {Object} colors App colors
* @property {Function} onPress onPress handler
* @property {Boolean} allowNavigation
*/
/**
* @typedef {Object} ProgressCircleComponentProps
* @param {boolean} isCompleted
* @param {number} progress,
* @param {Object} colors,
* @param {number} size,
* @param {number} thickness,
* @param {string} unfilledColor,
* @param {string} progressColor,
* @param {LocalImageSource} checkIcon
*/
/**
* @typedef {Object} ProgressBarComponentProps
* @param {number} progress
* @param {number} width
* @param {number} height
* @param {string} color
* @param {string} unfilledColor
* @param {RNStyleValue} style
*/
/**
* @typedef {Function} AssetFilterCallback
* @param {string} path
* @param {LocalImageSource} source
* @returns {LocalImageSource}
*/
/**
* @typedef {Function} TransformContentHeadersCallback
* @param {Object} headers
* @param {String} rootSiteUrl
* @param {String} url
* @param {String} accessToken
* @return {Object} - New headers object
*/
/**
* @typedef {Object} MoreScreenRendererProps
* @property {Object} screenProps
* @property {NavigationService} navigation
* @property {Object} settings App settings
* @property {MemberViewModel} user
* @property {Object} menuSettings Information about the menu such as items in the tab bar and in the more screen
* @property {Object} auth Logged-in user information
* @property {Function} onMenuItemPress Default navigation function or what was set in moreScreenApi.navigationHandler hook
* @property {Object} sections Menu items in more screen
*/
/**
* @class
* Screen Hooks.
* Instance name: screenHooksApi
You can use these hooks to customize different screen options such as hiding the user’s profile menu in the More screen, hiding the admin/author component and more.
* @example
* externalCodeSetup.screenHooksApi.METHOD_NAME
*/
export class ScreenHooksApi {
/* Version control screen */
versionControlIconRenderer = null;
/**
* Renders a component above the title on the Version control screen
* @deprecated
*/
setVersionControlIconRenderer = asset => {
this.versionControlIconRenderer = asset;
};
/* SocialLoginScreen */
// default order in which the soical login buttons are displayed
socialLoginButtonsOrder = ["apple", "twitter", "facebook", "google"];
/**
* Rearrange social login buttons
* @deprecated
* @param {Array<string>} list
*/
setSocialLoginButtonsOrder = newOrder => {
this.socialLoginButtonsOrder = newOrder;
};
/**
* @ignore
*/
addHomeScreenWidget = (widgetId, component, options) => {
console.warn("homescreen is obsolete, use app pages instead");
};
notificationsWidgetIconRenderer = null;
//UsersWidget icon in HomeScreen
usersWidgetIconRenderer = null;
//Activities icon in HomeScreen
activitiesWidgetIconRenderer = null;
// Always show Guthenberg blocks
forceShowBlocks = false;
/**
* You can set it to `true` to force using Gutenberg blocks on LearnDash screens. Default is `false`.
* @method
* @param {Boolean} forceShowBlocks
* @example
* externalCodeSetup.screenHooksApi.forceShowBlocks(true)
*/
setForceShowBlocks = forceShowBlocks => {
this.forceShowBlocks = forceShowBlocks;
};
musicController = null;
courseSingleHideAdmin = false;
/**
* You can use it to hide the admin/author component on the Single Course screen.
* @method
* @example
* externalCodeSetup.screenHooksApi.hideCourseSingleAdmin()
*/
hideCourseSingleAdmin = () => {
this.courseSingleHideAdmin = true;
};
// MoreScreen
customMoreScreenRenderer = null;
/**
* Lets you provide your own component for rendering More Screen content
* @method
* @param {MoreScreenRendererProps} MoreScreenRendererProps
* @example
* externalCodeSetup.screenHooksApi.setCustomMoreScreenRenderer((props) => {
*
* const {user} = props;
*
* if (user.followers < 100){
* return <View style={{flex: 1, alignSelf: "center", justifyContent: "center"}}>
*
* <Text> More features available when you reach 100 followers!</Text>
*
* </View>
* }
*
* //Return a more screen here as an else statement...
*
* });
*/
setCustomMoreScreenRenderer = renderer => {
this.customMoreScreenRenderer = renderer;
};
// Determines whether profile menu item appears on MoreScreen
moreScreenShowProfile = true;
/**
* Hides the user's profile menu item in the "More" Screen
* @method
* @example
* externalCodeSetup.screenHooksApi.disableProfileInMoreScreen();
*/
disableProfileInMoreScreen = () => {
this.moreScreenShowProfile = false;
};
// Sets header max height
setMusicController = component => (this.musicController = component);
// Back Button
BackButtonComponent = null;
/**
* Replaces the back button component in all app screens
* @method
* @param {BackButtonComponentProps} BackButtonComponent
* @example
* externalCodeSetup.screenHooksApi.setBackButtonRenderer(props => {
* return <Button title="Back" onPress={() => props.navigation.goBack()} />
* });
*
* @example <caption> Navigate to a user's profile </caption>
*
* //In custom_code/components/BackButton.js
*
* import React from "react";
* import { Button } from "react-native";
* import { useSelector } from "react-redux";
* import {CommonActions} from "@react-navigation/native";
*
* const BackButton = (props) => {
* const state = useSelector((state) => state);
*
* //Get a user object from the redux state..
* //In this case, redirect to own profile
* const user = state.user.userObject;
*
* const toProfile = () => {
*
* //Modify back button in a specific screen only. In this case, "Books" screen
* if (props.navigation.state?.params?.item?.label === "Books") {
* props.navigation.dispatch(
* CommonActions.navigate({
* name: "ProfileScreen",
* params: { user: user }
* })
* );
* } else {
* props.navigation.goBack()
* }
*
* }
*
* return <Button title="Back" onPress={() => toProfile()} />
* }
*
* export default BackButton;
*
* //In custom_code/index.js
*
* import BackButton from "./components/BackButton";
* export const applyCustomCode = externalCodeSetup => {
* externalCodeSetup.screenHooksApi.setBackButtonRenderer(props => <BackButton {...props} />);
* }
*/
setBackButtonRenderer = BackButtonComponent => {
this.BackButtonComponent = BackButtonComponent;
};
// filters and changes assets "require"
assetFilter = (path, required) => required;
/**
* You can use this to replace the user and lock icon in the "username or email" field and "password" field in the login screen.
* @method
* @param {AssetFilterCallback} assetFilter
* @example
* externalCodeSetup.screenHooksApi.setAssetFilter((path, source) => {
* if (path === "../assets/img/user.png") {
* return require("../assets/img/about.png")
* }
* return source
* })
*/
setAssetFilter = assetFilter => {
this.assetFilter = assetFilter;
};
ProgressListItemComponent = null;
/**
* Overrides the progress item component used in certain screens such as Course Quizzes Screen.
* @method
* @param {React.ComponentType<ProgressListItemComponentProps>} ProgressListItemComponent
* @example
* externalCodeSetup.screenHooksApi.setProgressListItemComponent(props => {
*
* const {item} = props;
*
* return <View style={{margin: 10}}>
* <Text>{item.title}</Text>
* <Text>{item.author.name}</Text>
* <Text>{item.link}</Text>
* </View>
* })
*/
setProgressListItemComponent = ProgressListItemComponent =>
(this.ProgressListItemComponent = ProgressListItemComponent);
ProgressCircleComponent = null;
/**
* @ignore
* Reason for ignore: ProgressCircleComponent is only used in CourseMenu.js but CourseMenu.js is not being used anywhere
* Custom component for rendering progress circle on items on Learhdash related screens, like lesson or topic item
* @method
* @param {React.ComponentType<ProgressCircleComponentProps>} ProgressCircleComponent
*/
setProgressCircleComponent = ProgressCircleComponent => {
this.ProgressCircleComponent = ProgressCircleComponent;
};
ProgressBarComponent = null;
/**
* @ignore
* Reason for ignore: ProgressBarComponent is not being used anywhere
* Custom component for rendering progress bar on courses
* @method
* @param {React.ComponentType<ProgressBarComponentProps>} ProgressBarComponent
*/
setProgressBarComponent = ProgressBarComponent =>
(this.ProgressBarComponent = ProgressBarComponent);
buildEmbedUrlHeaders = (headers, rootSiteUrl, url, accessToken) => headers;
/**
* If Gutenberg blocks are not used, then the course, lesson, topic and blog content fallbacks to show html to WebView.
* Use this method to pass additional headers to WebView if needed.
* @method
* @param {TransformContentHeadersCallback} buildEmbedUrlHeaders
* @example
* externalCodeSetup.screenHooksApi.setBuildEmbedUrlHeaders(props => {
* return {
* ...props,
* customHeader: "customHeader"
* }
* })
*/
setBuildEmbedUrlHeaders = buildEmbedUrlHeaders => {
this.buildEmbedUrlHeaders = buildEmbedUrlHeaders;
};
// Courses Widget Wrapper Switch set Count
wrapperSwitchCountCoursesWidget = count => count;
/**
* By default, the course widget component uses horizontal ScrollView if the total count of courses is equal or greater than 3.
* You can use this hook to set if the app will wrap the courses with horizontal ScrollView or just a View component.
* For example, if `wrapperSwitchCountCoursesWidget` is set to `1` while total count of courses is `10`, then the app will use the View component to wrap the widget.
* @method
* @param {Number} wrapperSwitchCountCoursesWidget
* @example
* externalCodeSetup.screenHooksApi.setWrapperSwitchCountCoursesWidget(1)
*/
setWrapperSwitchCountCoursesWidget = wrapperSwitchCountCoursesWidget =>
(this.wrapperSwitchCountCoursesWidget = wrapperSwitchCountCoursesWidget);
}
Source