import NativeTBLRNTTurboModule from '../NativeTBLRNTTurboModule'; import TBLClassicUnitController from './TBLClassicUnitController'; import { Platform } from 'react-native'; import { type TBLExtraProperties, TBLFetchingPolicy, TBLPlacementType, } from '../types'; import type { TBLClassicListener } from './TBLClassicListener'; import { isValid } from '../utils/TBLValidationUtils'; import { PLATFORMS } from '../consts'; /** * Represents a classic page in the Taboola React Native Plugin. * * The TBLClassicPage class is a core component of the Taboola SDK, responsible for managing * and displaying content recommendations on a specific screen within an application. * * Key Responsibilities: * - **Initialization**: Create an instance for each screen, specifying the `pageUrl` and `pageType` * to identify and categorize the content. * - **Content Management**: Acts as a container for multiple TBLClassicUnit instances, each representing * a specific placement on the screen, such as a widget or a feed. * - **Event Handling**: Works with TBLClassicListener to handle user interactions, allowing developers * to manage events like content clicks. * - **Content Fetching**: Facilitates the dynamic loading and display of content for the units associated * with the page. * * - The `buildUnit()` method is designed to be asynchronous to prevent blocking the UI thread. * - Native TBLClassicUnit creation occurs on the main thread via Turbo Modules, which by default * run on a background thread. * - This approach ensures smooth UI performance during unit initialization and content loading. * * This class provides methods to interact with and manipulate a Taboola page */ class TBLClassicPage { /** * The unique identifier for the page. */ public pageId: string | undefined; /** * Array to track all created TBLClassicUnitController instances */ private unitControllers: TBLClassicUnitController[] = []; /** * Constructs a new TBLClassicPage instance. * @param pageUrl - The URL of the page E.g. "https://www.example.com/articles?id=123". * @param pageType - The type of the page e.g. "article". */ constructor(pageUrl: string, pageType: string) { console.log('[TBLSOS] [TBLClassicPage.constructor] Entry', { pageUrl, pageType, }); if (!isValid(pageUrl, pageType)) { console.log( '[TBLSOS] [TBLClassicPage.constructor] Invalid pageUrl or pageType' ); console.error('getClassicPage requires valid pageUrl and pageType'); return; } console.log( '[TBLSOS] [TBLClassicPage.constructor] Calling NativeTBLRNTTurboModule.getClassicPage' ); this.pageId = NativeTBLRNTTurboModule.getClassicPage(pageUrl, pageType); console.log('[TBLSOS] [TBLClassicPage.constructor] Page created', { pageId: this.pageId, }); } /** * Builds a new TBLClassicUnit for the page. * @param placement - The placement name. * @param mode - The mode of the placement. * @param placementType - The type of the placement. * @param tblClassicListener * @returns A promise that resolves to a TBLClassicUnit. */ async buildUnit( placement: string, mode: string, placementType: TBLPlacementType, tblClassicListener: TBLClassicListener ): Promise { console.log('[TBLSOS] [TBLClassicPage.buildUnit] Entry', { pageId: this.pageId, placement, mode, placementType, }); if (!isValid(this.pageId, placement, mode)) { console.log( '[TBLSOS] [TBLClassicPage.buildUnit] Invalid initialization parameters', { pageId: this.pageId, placement, mode, } ); console.log('Invalid initialization parameters'); return undefined; } console.log('[TBLSOS] [TBLClassicPage.buildUnit] Creating unit controller'); const unitController = new TBLClassicUnitController( this.pageId!, placement, mode, placementType, tblClassicListener ); console.log( '[TBLSOS] [TBLClassicPage.buildUnit] Controller created, calling initialize' ); const initializedController = await unitController.initialize(); console.log('[TBLSOS] [TBLClassicPage.buildUnit] Controller initialized', { unitId: initializedController.unitId, pageId: initializedController.pageId, }); this.unitControllers.push(initializedController); console.log('[TBLSOS] [TBLClassicPage.buildUnit] Returning controller', { unitId: initializedController.unitId, totalUnits: this.unitControllers.length, }); return initializedController; } /** * Clears all unit controllers and their associated resources. * * This method: * - Removes all units from the page * - Clears event listeners for each unit * - Destroys WebView resources (Android) * - Makes all units unavailable for further use * * @warning After calling this method, all units become permanently unavailable * and cannot be reused. */ clearUnits(): void { this.unitControllers.forEach((tblClassicUnitController) => { tblClassicUnitController.clear(); }); console.log('[TBLClassicPage] All unit controllers cleared'); } /** * Sets extra properties for the page. * @param extraProperties - The extra properties to set. */ setPageExtraProperties(extraProperties: TBLExtraProperties): void { if (isValid(this.pageId, extraProperties)) { NativeTBLRNTTurboModule.setPageExtraProperties( this.pageId!, extraProperties ); } else { console.error( '[TBLClassicPage] Invalid arguments for setPageExtraProperties' ); } } /** * Resets the page and clears all unit controllers */ reset(): void { if (isValid(this.pageId)) { NativeTBLRNTTurboModule.resetPage(this.pageId!); } else { console.error('[TBLClassicPage] Invalid pageId for reset'); } } /** * Refreshes the page. */ refresh(): void { if (isValid(this.pageId)) { NativeTBLRNTTurboModule.refreshPage(this.pageId!); } else { console.error('[TBLClassicPage] Invalid pageId for refresh'); } } /** * Gets the page view ID. * @returns The page view ID, or undefined if invalid. */ getPageViewId(): string | undefined { if (isValid(this.pageId)) { return NativeTBLRNTTurboModule.getPageViewId(this.pageId!); } console.error('[TBLClassicPage] Invalid pageId for getPageViewId'); return undefined; } /** * Sets the serial fetch timeout for the page. * @param timeoutMillis - The timeout in milliseconds. */ setSerialFetchTimeout(timeoutMillis: number): void { if (isValid(this.pageId, timeoutMillis)) { NativeTBLRNTTurboModule.setSerialFetchTimeout( this.pageId!, timeoutMillis ); } else { console.error( '[TBLClassicPage] Invalid arguments for setSerialFetchTimeout' ); } } /** * Sets the URL for the page. * @param pageUrl - The new URL for the page. */ setPageUrl(pageUrl: string): void { if (isValid(this.pageId, pageUrl)) { if (Platform.OS === PLATFORMS.ANDROID) { NativeTBLRNTTurboModule.setPageUrl(this.pageId!, pageUrl); } } else { console.error('[TBLClassicPage] Invalid arguments for setPageUrl'); } } /** * Sets the target type for the page. * @param targetType - The target type to set. */ setTargetType(targetType: string): void { if (isValid(this.pageId, targetType)) { if (Platform.OS === PLATFORMS.ANDROID) { NativeTBLRNTTurboModule.setPageTargetType(this.pageId!, targetType); } } else { console.error('[TBLClassicPage] Invalid arguments for setTargetType'); } } /** * Sets the type of the page. * @param pageType - The new type for the page. */ setPageType(pageType: string): void { if (Platform.OS === PLATFORMS.ANDROID) { if (isValid(this.pageId, pageType)) { NativeTBLRNTTurboModule.setPageType(this.pageId!, pageType); } } else { console.error('[TBLClassicPage] Invalid arguments for setPageType'); } } /** * Sets whether the page should auto-resize its height. * @param autoResizeHeight - Whether to enable auto-resize. */ setAutoResizeHeight(autoResizeHeight: boolean): void { if (isValid(this.pageId, autoResizeHeight)) { if (Platform.OS === PLATFORMS.ANDROID) { NativeTBLRNTTurboModule.setAutoResizeHeight( this.pageId!, autoResizeHeight ); } } else { console.error( '[TBLClassicPage] Invalid arguments for setAutoResizeHeight' ); } } /** * Sets a tag for the page. * @param tag - The tag to set. */ setTag(tag: string): void { if (isValid(this.pageId, tag)) { if (Platform.OS === PLATFORMS.ANDROID) { NativeTBLRNTTurboModule.setPageTag(this.pageId!, tag); } } else { console.error('[TBLClassicPage] Invalid arguments for setTag'); } } /** * Sets the user ID for the page. * @param userId - The user ID to set. */ setUserId(userId: string): void { if (isValid(this.pageId, userId)) { NativeTBLRNTTurboModule.setPageUserId(this.pageId!, userId); } else { console.error('[TBLClassicPage] Invalid arguments for setUserId'); } } /** * Sets the publisher for the page. * @param publisher - The publisher to set. */ setPublisher(publisher: string): void { if (isValid(this.pageId, publisher)) { if (Platform.OS === PLATFORMS.ANDROID) { NativeTBLRNTTurboModule.setPagePublisher(this.pageId!, publisher); } } else { console.error('[TBLClassicPage] Invalid arguments for setPublisher'); } } /** * Updates the page ID. * @param updatedPageId - The new page ID. */ setPageId(updatedPageId: string): void { if (isValid(this.pageId, updatedPageId)) { NativeTBLRNTTurboModule.setPageId(this.pageId!, updatedPageId); } else { console.error('[TBLClassicPage] Invalid arguments for setPageId'); } } /** * Sets the fetching policy for the page. * @param fetchingPolicy - The fetching policy to set. */ setFetchingPolicy(fetchingPolicy: TBLFetchingPolicy): void { if (isValid(this.pageId, fetchingPolicy)) { if (Platform.OS === PLATFORMS.IOS) { NativeTBLRNTTurboModule.setFetchingPolicy(this.pageId!, fetchingPolicy); } } else { console.error('[TBLClassicPage] Invalid arguments for setFetchingPolicy'); } } /** * Clears all fetch requests for the page. */ clearAllFetchRequests(): void { if (isValid(this.pageId)) { if (Platform.OS === PLATFORMS.IOS) { NativeTBLRNTTurboModule.clearAllFetchRequests(this.pageId!); } } else { console.error( '[TBLClassicPage] Invalid pageId for clearAllFetchRequests' ); } } /** * Fetches all units content for the page. */ fetchAllUnitsContent(): void { if (isValid(this.pageId)) { NativeTBLRNTTurboModule.fetchAllUnitsContent(this.pageId!); } else { console.error('[TBLClassicPage] Invalid pageId for fetchAllUnitsContent'); } } } export default TBLClassicPage;