Source

externalCode/blocks.js

import * as React from "react";

/**
 * Types
 */

/**
 * @typedef {Object} BlockProps
 * @property {Object} block Block data from API
 * @property {Function} calcFontSize Used to calculate font size based on the fixed value you assign and percent set on branding options
 * @property {Object} colors App colors
 * @property {Object} fontFamilyStyle App font style
 * @property {Object} global App global style
 * @property {Function} handleLinkClicks Link click handler
 * @property {Function} htmlHandleClicks Link click handler for webview
 * @property {boolean} isNavActive Returns true if current screen is visible
 * @property {boolean} lastItem Returns true if component is last block
 * @property {NavigationService} navigation
 * @property {ToUserBasedOnSettings} toUserBasedOnSettings
 * @property {number} viewWidth Default window width used by blocks
 * @property {Function} wrapHtml Function that will wrap string in an HTML template
 * @property {ReactStyles} wrapStyle Default wrap style used by blocks
 */

/**
 * A custom block render function
 * @typedef {Function} CustomBlockRenderCallback
 * @param {BlockProps} renderer
 * @return {React.ComponentType<any>} React Component
 */

/**
 * Block props
 * @typedef {Function} CustomBlockPropsCallback
 * @param {BlockProps} renderer
 * @return {Object} New props
 */

/**
 * @typedef {"core/image" | "core/video" | "core/audio" | "core/gallery" | "core/paragraph" | "core/heading" | "core/quote" | "core/table" | "core/list" | "core/html" | "core/cover" | "core/media-text" | "core/buttons" | "core/button" | "core/columns" | "core/embed" | "bbapp/courses" | "bbapp/topics" | "bbapp/forums" | "bbapp/groups" | "bbapp/members" | "bbapp/activity" | "bbapp/notifications" | "bbapp/qlinks" | "bbapp/h5p" | "tincanny/content" | "core/code" | "core/pullquote" | "core/preformatted" | "core/verse" | "core/file" | "core/more" | "core/nextpage" | "core/separator" | "core/spacer" | "core/group"} BlockTypes
 */

/**
 * @class
 * Blocks Hooks.
 * Instance name: blocksApi
  
  Enables you to make modifications to the different blocks and replace default behaviour in your app pages in terms of appearance as well as functionality.
 * @example
 * externalCodeSetup.blocksApi.METHOD_NAME
 */
export class BlocksApi {
	/**
	 * @private
	 * @property {Object<string, CustomBlockRenderCallback>} customBlockRenders
	 */
	customBlockRenders = {};

	/**
	 * @deprecated
	 * @private
	 * @property {?number} profileBlockBgImage
	 */
	profileBlockBgImage = null;

	/**
	 * @deprecated
	 * Changes the Profile Block cover image
	 * @method
	 * @param {number} image - Image resourse (via request('...src'))
	 */
	setProfileBlockBgImage = image => {
		this.profileBlockBgImage = image;
	};

	/**
	 * Replaces the Gutenberg blocks that match with blockType using the render function.
	 * @method
	 * @param {BlockTypes} blockType Block identifier
	 * @param {CustomBlockRenderCallback} renderer Render function
	 * @example <caption>User would like to customize the component when Video block is used</caption>
	 *
	 * externalCodeSetup.blocksApi.addCustomBlockRender("core/video", (props) => {
	 *   const { block } = props;
	 *   const VideoComponent =
	 *   <>
	 *       <WebView
	 *           source={{
	 *               html: `<video width="980" playsinline controls autoplay src="${block.content}" ></video>`
	 *           }}
	 *           useWebKit={true}
	 *           originWhitelist={['*']}
	 *           allowsInlineMediaPlayback={true}
	 *           style={{
	 *               height: 250,
	 *               width: "auto",
	 *           }}/>
	 *
	 *      <View>
	 *           <Text> Watch our awesome video! </Text>
	 *      </View>
	 *   </>
	 *   return VideoComponent;
	 * });
	 */
	addCustomBlockRender = (blockType, renderer) => {
		this.customBlockRenders[blockType] = renderer;
	};

	blockProps = {};
	/**
	 * You can use this hook to modify the properties of the Gutenberg blocks.
	 * For example, you can modify the width of the video block to let it occupy the full width on any device.
	 * @method
	 * @param {BlockTypes} blockType Block identifier
	 * @param {CustomBlockPropsCallback} props
	 * @example <caption>Extend the width of video blocks used in lesson single screen </caption>
	 *
	 * import { Platform } from 'react-native'
	 * import {DEVICE_WIDTH} from "@src/styles/global";
	 * export const applyCustomCode = externalCodeSetup => {
	 *
	 *   if (! Platform.isPad){
	 *      externalCodeSetup.cssApi.addGlobalStyle("lessonSingleScreenBlockContainer", { paddingHorizontal: 0 }, true);
	 *      externalCodeSetup.cssApi.addGlobalStyle("videoBlockContainer", { paddingHorizontal: 0 });
	 *
	 *      externalCodeSetup.blocksApi.setBlockProps("core/embed", (props) => {
	 *
	 *         const {block} = props;
	 *
	 *         if (block.data.provider === "vimeo" || block.data.provider === "youtube"){
	 *            return {
	 *               ...props,
	 *               viewWidth: DEVICE_WIDTH
	 *            }
	 *         }
	 *
	 *         return props;
	 *      });
	 *
	 *   }
	 * }
	 */
	setBlockProps = (blockType, blockProps) => {
		this.blockProps[blockType] = blockProps;
	};
}