diff --git a/apps/AEPSampleAppNewArchEnabled/app/_layout.tsx b/apps/AEPSampleAppNewArchEnabled/app/_layout.tsx index 1168cf88b..f22c563d2 100644 --- a/apps/AEPSampleAppNewArchEnabled/app/_layout.tsx +++ b/apps/AEPSampleAppNewArchEnabled/app/_layout.tsx @@ -42,7 +42,7 @@ export default function RootLayout() { // For class components, call initializeWithAppId inside componentDidMount. MobileCore.setLogLevel(LogLevel.DEBUG); MobileCore.initializeWithAppId( - "3149c49c3910/473386a6e5b0/launch-6099493a8c97-development" + "staging/1b50a869c4a2/bcd1a623883f/launch-e44d085fc760-development" ) .then(() => { console.log("AEP SDK Initialized"); diff --git a/packages/messaging/src/ContentCardMappingManager.ts b/packages/messaging/src/ContentCardMappingManager.ts deleted file mode 100644 index 14cdb3243..000000000 --- a/packages/messaging/src/ContentCardMappingManager.ts +++ /dev/null @@ -1,104 +0,0 @@ -/* - Copyright 2025 Adobe. All rights reserved. - This file is licensed to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance with the License. - You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law - or agreed to in writing, software distributed under the License is - distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF - ANY KIND, either express or implied. See the License for the specific - language governing permissions and limitations under the License. -*/ - -import { ContentCard } from './models/ContentCard'; -import { MessagingProposition } from './models/MessagingProposition'; - -export interface ContentCardMapping { - contentCard: ContentCard; - proposition: MessagingProposition; -} - -/** - * Singleton manager for content card mapping functionality. - * Provides a centralized way to manage mappings between content card IDs and their corresponding objects. - */ -export class ContentCardMappingManager { - private static instance: ContentCardMappingManager; - private contentCardMap: Map = new Map(); - - private constructor() { } - - /** - * Gets the singleton instance of ContentCardMappingManager. - * @returns ContentCardMappingManager The singleton instance - */ - public static getInstance(): ContentCardMappingManager { - if (!ContentCardMappingManager.instance) { - ContentCardMappingManager.instance = new ContentCardMappingManager(); - } - return ContentCardMappingManager.instance; - } - - /** - * Gets the content card and proposition objects for a given content card ID. - * @param contentCardId The ID of the content card - * @returns ContentCardMapping | undefined The content card and proposition objects, or undefined if not found - */ - getContentCardMapping(contentCardId: string): ContentCardMapping | undefined { - return this.contentCardMap.get(contentCardId); - } - - /** - * Adds a mapping for a content card ID with its corresponding content card and proposition objects. - * @param contentCardId The ID of the content card - * @param contentCard The content card object - * @param proposition The proposition object - */ - addMapping(contentCardId: string, contentCard: ContentCard, proposition: MessagingProposition): void { - this.contentCardMap.set(contentCardId, { - contentCard: contentCard, - proposition: proposition - }); - } - - /** - * Removes a mapping for a specific content card ID. - * @param contentCardId The ID of the content card to remove - * @returns boolean True if the mapping was removed, false if it didn't exist - */ - removeMapping(contentCardId: string): boolean { - return this.contentCardMap.delete(contentCardId); - } - - /** - * Clears all mappings. - */ - clearMappings(): void { - this.contentCardMap.clear(); - } - - /** - * Checks if a mapping exists for a given content card ID. - * @param contentCardId The ID of the content card - * @returns boolean True if the mapping exists, false otherwise - */ - hasMapping(contentCardId: string): boolean { - return this.contentCardMap.has(contentCardId); - } - - /** - * Gets the total number of mappings. - * @returns number The number of mappings - */ - getMappingCount(): number { - return this.contentCardMap.size; - } - - /** - * Gets all content card IDs that have mappings. - * @returns string[] Array of content card IDs - */ - getAllContentCardIds(): string[] { - return Array.from(this.contentCardMap.keys()); - } -} \ No newline at end of file diff --git a/packages/messaging/src/ContentProvider.ts b/packages/messaging/src/ContentProvider.ts index 72066e055..2106c9226 100644 --- a/packages/messaging/src/ContentProvider.ts +++ b/packages/messaging/src/ContentProvider.ts @@ -13,7 +13,6 @@ import { SmallImageContentData, LargeImageContentData, ImageOnlyContentData } fr import Messaging from "./Messaging"; import { PersonalizationSchema } from "./models/PersonalizationSchema"; import { ContentCard } from "./models/ContentCard"; -import { ContentCardMappingManager } from "./ContentCardMappingManager"; /** Represents template types for AepUI templates. */ export enum TemplateType { @@ -35,12 +34,13 @@ export interface ContentTemplate { // TODO: add metadata here .... } +export const fetchedContentCards: Map = new Map(); + export class ContentProvider { - private mappingManager: ContentCardMappingManager; + // cached fetetched content card objects constructor(private readonly surface: string) { - this.mappingManager = ContentCardMappingManager.getInstance(); } //TODO: it looks like this is not useful, it might be beeeter to remove it and move getContent() to the Messaging class @@ -74,7 +74,7 @@ export class ContentProvider { const contentCard = item as ContentCard; // Add to the mapping manager for tracking purposes - this.mappingManager.addMapping(contentCard.id, contentCard, proposition); + fetchedContentCards.set(contentCard.id, contentCard); const templateType = contentCard.data?.meta?.adobe?.template as string; switch (templateType) { case "SmallImage": diff --git a/packages/messaging/src/ContentView.tsx b/packages/messaging/src/ContentView.tsx index ee9c119c4..22b497a6e 100644 --- a/packages/messaging/src/ContentView.tsx +++ b/packages/messaging/src/ContentView.tsx @@ -19,9 +19,9 @@ import { ImageOnlyContent, ImageOnlyContentStyle, } from "@adobe/react-native-aepui"; -import { ContentCardMappingManager } from "./ContentCardMappingManager"; -import Messaging from "./Messaging"; +import { fetchedContentCards } from "./ContentProvider"; import { ContentViewEvent } from "@adobe/react-native-aepui"; +import { MessagingEdgeEventType } from "./models/Trackable"; export interface ContentViewProps { data: ContentTemplate; @@ -41,8 +41,9 @@ export const ContentView: React.FC = ({ listener, }) => { const [isVisible, setIsVisible] = useState(true); - const contentCardMapping = - ContentCardMappingManager.getInstance().getContentCardMapping(data.id); + const contentCard = fetchedContentCards.get(data.id); + // const contentCardMapping = + // ContentCardMappingManager.getInstance().getContentCardMapping(data.id); // Track if onDisplay was already called to prevent duplicates const displayedRef = useRef(false); @@ -53,21 +54,18 @@ export const ContentView: React.FC = ({ // Handle dismiss event by hiding the content view if (event === "onDismiss") { setIsVisible(false); + if (contentCard) { + contentCard.track(MessagingEdgeEventType.DISMISS); + } } - if (event === "clickButton" && contentCardMapping) { - console.log("trackContentCardInteraction", contentCardMapping); - Messaging.trackContentCardInteraction( - contentCardMapping.proposition, - contentCardMapping.contentCard - ); + if (event === "clickButton" && contentCard) { + console.log("trackContentCardInteraction", contentCard); + contentCard.track(MessagingEdgeEventType.INTERACT); } - if (event === "onDisplay" && contentCardMapping) { - console.log("trackContentCardDisplay", contentCardMapping); - Messaging.trackContentCardDisplay( - contentCardMapping.proposition, - contentCardMapping.contentCard - ); + if (event === "onDisplay" && contentCard) { + console.log("trackContentCardDisplay", contentCard); + contentCard.track(MessagingEdgeEventType.DISPLAY); } if (listener) { @@ -115,7 +113,7 @@ export const ContentView: React.FC = ({ return ( diff --git a/packages/messaging/src/models/ContentCard.ts b/packages/messaging/src/models/ContentCard.ts index f732d8f80..821888dc5 100644 --- a/packages/messaging/src/models/ContentCard.ts +++ b/packages/messaging/src/models/ContentCard.ts @@ -11,11 +11,12 @@ */ import { PersonalizationSchema } from './PersonalizationSchema'; +import { Trackable } from './Trackable'; type ContentCardTemplate = 'SmallImage'; type DismissButtonStyle = 'circle' | 'none' | 'simple'; -export interface ContentCard { +export interface ContentCard extends Trackable { id: string; data: { contentType: 'application/json'; diff --git a/packages/messaging/src/models/Trackable.ts b/packages/messaging/src/models/Trackable.ts new file mode 100644 index 000000000..d3e3e1d11 --- /dev/null +++ b/packages/messaging/src/models/Trackable.ts @@ -0,0 +1,30 @@ + +/* + Copyright 2025 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance with the License. + You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law + or agreed to in writing, software distributed under the License is + distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF + ANY KIND, either express or implied. See the License for the specific + language governing permissions and limitations under the License. +*/ + +//TODO: This is the mock code for the further tracking integration. Remove it once the tracking API is implemented. + +export interface Trackable { + track(type: MessagingEdgeEventType): void; + // internally call the below function to send the track events. + // track(interaction: string, type: MessagingEdgeEventType, tokens?: [string]): void; +} + +export enum MessagingEdgeEventType { + DISMISS = "dismiss", + INTERACT = "interact", + TRIGGER = "trigger", + DISPLAY = "display", + DISQUALIFY = "disqualify", + QUALIFY = "qualify", + SUPPRESS_DISPLAY = "suppressDisplay" +} \ No newline at end of file