diff --git a/src/IterableAction.ts b/src/IterableAction.ts deleted file mode 100644 index 3b9c6857a..000000000 --- a/src/IterableAction.ts +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Enum representing the source of IterableAction. - */ -export enum IterableActionSource { - push = 0, - appLink = 1, - inApp = 2, -} - -/** - * Enum representing what level of logs will Android and iOS project be printing on their consoles respectively. - */ -export enum IterableLogLevel { - debug = 1, - info = 2, - error = 3, -} - -/** - * IterableAction represents an action defined as a response to user events. - * It is currently used in push notification actions (open push & action buttons). - */ -export class IterableAction { - type: string; - data?: string; - userInput?: string; - - constructor(type: string, data?: string, userInput?: string) { - this.type = type; - this.data = data; - this.userInput = userInput; - } - - static fromDict(dict: any): IterableAction { - return new IterableAction(dict.type, dict.data, dict.userInput); - } -} - -export class IterableActionContext { - action: IterableAction; - source: IterableActionSource; - - constructor(action: IterableAction, source: IterableActionSource) { - this.action = action; - this.source = source; - } - - static fromDict(dict: any): IterableActionContext { - const action = IterableAction.fromDict(dict.action); - const source = dict.source as IterableActionSource; - return new IterableActionContext(action, source); - } -} diff --git a/src/IterableInAppClasses.ts b/src/IterableInAppClasses.ts deleted file mode 100644 index 83a30cbb8..000000000 --- a/src/IterableInAppClasses.ts +++ /dev/null @@ -1,132 +0,0 @@ -/** - * TODO: Break this file into multiple files - */ - -// TODO: Add description -export enum IterableInAppShowResponse { - /** Show in-app */ - show = 0, - /** Skip showing in-app */ - skip = 1, -} - -// TODO: Add description -export enum IterableInAppTriggerType { - /** Tries to display the in-app automatically immediately */ - immediate = 0, - /** Used for Push to in-app */ - event = 1, - /** Do not display the in-app automatically via the SDK */ - never = 2, -} - -// TODO: Add description -export class IterableInAppTrigger { - type: IterableInAppTriggerType; - - constructor(type: IterableInAppTriggerType) { - this.type = type; - } - - static fromDict(dict: any): IterableInAppTrigger { - const type = dict.type as - | IterableInAppTriggerType - | IterableInAppTriggerType.immediate; - return new IterableInAppTrigger(type); - } -} - -// TODO: Add description -export enum IterableInAppContentType { - html = 0, - alert = 1, - banner = 2, -} - -// TODO: Add description -export enum IterableInAppLocation { - inApp = 0, - inbox = 1, -} - -// TODO: Add description -export enum IterableInAppCloseSource { - back = 0, - link = 1, - unknown = 100, -} - -// TODO: Add description -export enum IterableInAppDeleteSource { - inboxSwipe = 0, - deleteButton = 1, - unknown = 100, -} - -// TODO: Add description -export class IterableEdgeInsets { - top: number; - left: number; - bottom: number; - right: number; - - constructor(top: number, left: number, bottom: number, right: number) { - this.top = top; - this.left = left; - this.bottom = bottom; - this.right = right; - } - - static fromDict(dict: any): IterableEdgeInsets { - return new IterableEdgeInsets( - dict.top as number, - dict.left as number, - dict.bottom as number, - dict.right as number - ); - } -} - -// TODO: Add description -export interface IterableInAppContent { - type: IterableInAppContentType; -} - -// TODO: Add description -export class IterableHtmlInAppContent implements IterableInAppContent { - type: IterableInAppContentType = IterableInAppContentType.html; - edgeInsets: IterableEdgeInsets; - html: string; - - constructor(edgeInsets: IterableEdgeInsets, html: string) { - this.edgeInsets = edgeInsets; - this.html = html; - } - - static fromDict(dict: any): IterableHtmlInAppContent { - return new IterableHtmlInAppContent( - IterableEdgeInsets.fromDict(dict.edgeInsets), - dict.html as string - ); - } -} - -export class IterableInboxMetadata { - title?: string; - subtitle?: string; - icon?: string; - - constructor( - title: string | undefined, - subtitle: string | undefined, - icon: string | undefined - ) { - this.title = title; - this.subtitle = subtitle; - this.icon = icon; - } - - static fromDict(dict: any): IterableInboxMetadata { - return new IterableInboxMetadata(dict.title, dict.subtitle, dict.icon); - } -} diff --git a/src/__mocks__/MockRNIterableAPI.ts b/src/__mocks__/MockRNIterableAPI.ts index 564cb26eb..36c8daa1d 100644 --- a/src/__mocks__/MockRNIterableAPI.ts +++ b/src/__mocks__/MockRNIterableAPI.ts @@ -1,5 +1,5 @@ -import { IterableAttributionInfo } from '../Iterable'; -import { IterableInAppMessage } from '../IterableInAppMessage'; +import { IterableAttributionInfo } from '../core'; +import { IterableInAppMessage } from '../inApp'; export class MockRNIterableAPI { static email?: string; diff --git a/src/__mocks__/index.ts b/src/__mocks__/index.ts new file mode 100644 index 000000000..1fac4fe8c --- /dev/null +++ b/src/__mocks__/index.ts @@ -0,0 +1,2 @@ +export * from './MockLinking'; +export * from './MockRNIterableAPI'; diff --git a/src/__tests__/Iterable.test.ts b/src/__tests__/Iterable.test.ts index a257c8f0c..4ba387deb 100644 --- a/src/__tests__/Iterable.test.ts +++ b/src/__tests__/Iterable.test.ts @@ -2,24 +2,21 @@ import { NativeEventEmitter } from 'react-native'; import { MockLinking } from '../__mocks__/MockLinking'; import { MockRNIterableAPI } from '../__mocks__/MockRNIterableAPI'; -import { TestHelper } from './TestHelper'; - +import { IterableLogger } from '../core'; // import from the same location that consumers import from import { Iterable, IterableAction, IterableActionContext, IterableActionSource, - IterableConfig, - IterableLogLevel, -} from '../index'; -import { - EventName, IterableAttributionInfo, IterableCommerceItem, -} from '../Iterable'; -import { IterableDataRegion } from '../IterableDataRegion'; -import { IterableLogger } from '../IterableLogger'; + IterableConfig, + IterableDataRegion, + IterableEventName, + IterableLogLevel, +} from '..'; +import { TestHelper } from './TestHelper'; describe('Iterable', () => { beforeEach(() => { @@ -253,7 +250,7 @@ describe('Iterable', () => { ); // sets up event emitter const nativeEmitter = new NativeEventEmitter(); - nativeEmitter.removeAllListeners(EventName.handleUrlCalled); + nativeEmitter.removeAllListeners(IterableEventName.handleUrlCalled); // sets up config file and urlHandler function // urlHandler set to return false const config = new IterableConfig(); @@ -276,7 +273,7 @@ describe('Iterable', () => { context: { action: actionDict, source: 'inApp' }, }; // WHEN handleUrlCalled event is emitted - nativeEmitter.emit(EventName.handleUrlCalled, dict); + nativeEmitter.emit(IterableEventName.handleUrlCalled, dict); // THEN urlHandler and MockLinking is called with expected url return await TestHelper.delayed(0, () => { expect(config.urlHandler).toBeCalledWith(expectedUrl, dict.context); @@ -289,7 +286,7 @@ describe('Iterable', () => { ); // sets up event emitter const nativeEmitter = new NativeEventEmitter(); - nativeEmitter.removeAllListeners(EventName.handleUrlCalled); + nativeEmitter.removeAllListeners(IterableEventName.handleUrlCalled); // sets up config file and urlHandler function // urlHandler set to return false const config = new IterableConfig(); @@ -312,7 +309,7 @@ describe('Iterable', () => { context: { action: actionDict, source: 'inApp' }, }; // WHEN handleUrlCalled event is emitted - nativeEmitter.emit(EventName.handleUrlCalled, dict); + nativeEmitter.emit(IterableEventName.handleUrlCalled, dict); // THEN urlHandler is called and MockLinking.openURL is not called return await TestHelper.delayed(0, () => { expect(config.urlHandler).toBeCalledWith(expectedUrl, dict.context); @@ -325,7 +322,7 @@ describe('Iterable', () => { ); // sets up event emitter const nativeEmitter = new NativeEventEmitter(); - nativeEmitter.removeAllListeners(EventName.handleUrlCalled); + nativeEmitter.removeAllListeners(IterableEventName.handleUrlCalled); // sets up config file and urlHandler function // urlHandler set to return true const config = new IterableConfig(); @@ -348,7 +345,7 @@ describe('Iterable', () => { context: { action: actionDict, source: 'inApp' }, }; // WHEN handleUrlCalled event is emitted - nativeEmitter.emit(EventName.handleUrlCalled, dict); + nativeEmitter.emit(IterableEventName.handleUrlCalled, dict); // THEN urlHandler is called and MockLinking.openURL is not called return await TestHelper.delayed(0, () => { expect(config.urlHandler).toBeCalledWith(expectedUrl, dict.context); @@ -361,7 +358,9 @@ describe('Iterable', () => { ); // sets up event emitter const nativeEmitter = new NativeEventEmitter(); - nativeEmitter.removeAllListeners(EventName.handleCustomActionCalled); + nativeEmitter.removeAllListeners( + IterableEventName.handleCustomActionCalled + ); // sets up config file and customActionHandler function // customActionHandler set to return true const config = new IterableConfig(); @@ -382,7 +381,7 @@ describe('Iterable', () => { context: { action: actionDict, source: IterableActionSource.inApp }, }; // WHEN handleCustomActionCalled event is emitted - nativeEmitter.emit(EventName.handleCustomActionCalled, dict); + nativeEmitter.emit(IterableEventName.handleCustomActionCalled, dict); // THEN customActionHandler is called with expected action and expected context const expectedAction = new IterableAction(actionName, actionData); const expectedContext = new IterableActionContext( diff --git a/src/__tests__/IterableInApp.test.ts b/src/__tests__/IterableInApp.test.ts index 110bcb47f..c322d7c5a 100644 --- a/src/__tests__/IterableInApp.test.ts +++ b/src/__tests__/IterableInApp.test.ts @@ -1,20 +1,21 @@ import { NativeEventEmitter } from 'react-native'; +import { IterableLogger } from '../core'; import { MockRNIterableAPI } from '../__mocks__/MockRNIterableAPI'; -import { Iterable, EventName } from '../Iterable'; -import { IterableConfig } from '../IterableConfig'; -import { IterableInAppMessage } from '../IterableInAppMessage'; import { + Iterable, + IterableConfig, + IterableEventName, + IterableInAppCloseSource, + IterableInAppDeleteSource, IterableInAppLocation, + IterableInAppMessage, + IterableInAppShowResponse, IterableInAppTrigger, IterableInAppTriggerType, IterableInboxMetadata, - IterableInAppCloseSource, - IterableInAppShowResponse, - IterableInAppDeleteSource, -} from '../IterableInAppClasses'; -import { IterableLogger } from '../IterableLogger'; +} from '..'; describe('Iterable In App', () => { beforeEach(() => { @@ -137,7 +138,7 @@ describe('Iterable In App', () => { test('inAppHandler_messageAndEventEmitted_methodCalledWithMessage', () => { // sets up event emitter const nativeEmitter = new NativeEventEmitter(); - nativeEmitter.removeAllListeners(EventName.handleInAppCalled); + nativeEmitter.removeAllListeners(IterableEventName.handleInAppCalled); // sets up config file and inAppHandler function const config = new IterableConfig(); @@ -170,7 +171,7 @@ describe('Iterable In App', () => { ); // WHEN handleInAppCalled event is emitted - nativeEmitter.emit(EventName.handleInAppCalled, messageDict); + nativeEmitter.emit(IterableEventName.handleInAppCalled, messageDict); // THEN inAppHandler and MockRNIterableAPI.setInAppShowResponse is called with message expect(config.inAppHandler).toBeCalledWith(expectedMessage); diff --git a/src/Iterable.ts b/src/core/classes/Iterable.ts similarity index 85% rename from src/Iterable.ts rename to src/core/classes/Iterable.ts index 25313f35f..e2bc169ac 100644 --- a/src/Iterable.ts +++ b/src/core/classes/Iterable.ts @@ -1,7 +1,3 @@ -/** - * TODO: Split into seperate files - */ - import { Linking, NativeEventEmitter, @@ -9,85 +5,26 @@ import { Platform, } from 'react-native'; -import { IterableAction, IterableActionContext } from './IterableAction'; -import { IterableConfig, AuthResponse } from './IterableConfig'; import { IterableInAppCloseSource, IterableInAppDeleteSource, IterableInAppLocation, -} from './IterableInAppClasses'; - -import { IterableInAppManager } from './IterableInAppManager'; -import { IterableInAppMessage } from './IterableInAppMessage'; + IterableInAppManager, + IterableInAppMessage, +} from '../../inApp'; +import { IterableAuthResponseResult, IterableEventName } from '../enums'; + +import { IterableAction } from './IterableAction'; +import { IterableActionContext } from './IterableActionContext'; +import { IterableAttributionInfo } from './IterableAttributionInfo'; +import { IterableAuthResponse } from './IterableAuthResponse'; +import type { IterableCommerceItem } from './IterableCommerceItem'; +import { IterableConfig } from './IterableConfig'; import { IterableLogger } from './IterableLogger'; const RNIterableAPI = NativeModules.RNIterableAPI; const RNEventEmitter = new NativeEventEmitter(RNIterableAPI); -enum AuthResponseCallback { - SUCCESS, - FAILURE, -} - -export class IterableAttributionInfo { - campaignId: number; - templateId: number; - messageId: string; - - constructor(campaignId: number, templateId: number, messageId: string) { - this.campaignId = campaignId; - this.templateId = templateId; - this.messageId = messageId; - } -} - -export class IterableCommerceItem { - id: string; - name: string; - price: number; - quantity: number; - sku?: string; - description?: string; - url?: string; - imageUrl?: string; - categories?: Array; - dataFields?: any; - - constructor( - id: string, - name: string, - price: number, - quantity: number, - sku?: string, - description?: string, - url?: string, - imageUrl?: string, - categories?: Array, - dataFields?: any | undefined - ) { - this.id = id; - this.name = name; - this.price = price; - this.quantity = quantity; - this.sku = sku; - this.description = description; - this.url = url; - this.imageUrl = imageUrl; - this.categories = categories; - this.dataFields = dataFields; - } -} - -export enum EventName { - handleUrlCalled = 'handleUrlCalled', - handleCustomActionCalled = 'handleCustomActionCalled', - handleInAppCalled = 'handleInAppCalled', - handleAuthCalled = 'handleAuthCalled', - receivedIterableInboxChanged = 'receivedIterableInboxChanged', - handleAuthSuccessCalled = 'handleAuthSuccessCalled', - handleAuthFailureCalled = 'handleAuthFailureCalled', -} - export class Iterable { static inAppManager = new IterableInAppManager(); @@ -602,13 +539,15 @@ export class Iterable { // PRIVATE private static setupEventHandlers() { //Remove all listeners to avoid duplicate listeners - RNEventEmitter.removeAllListeners(EventName.handleUrlCalled); - RNEventEmitter.removeAllListeners(EventName.handleInAppCalled); - RNEventEmitter.removeAllListeners(EventName.handleCustomActionCalled); - RNEventEmitter.removeAllListeners(EventName.handleAuthCalled); + RNEventEmitter.removeAllListeners(IterableEventName.handleUrlCalled); + RNEventEmitter.removeAllListeners(IterableEventName.handleInAppCalled); + RNEventEmitter.removeAllListeners( + IterableEventName.handleCustomActionCalled + ); + RNEventEmitter.removeAllListeners(IterableEventName.handleAuthCalled); if (Iterable.savedConfig.urlHandler) { - RNEventEmitter.addListener(EventName.handleUrlCalled, (dict) => { + RNEventEmitter.addListener(IterableEventName.handleUrlCalled, (dict) => { const url = dict.url; const context = IterableActionContext.fromDict(dict.context); Iterable.wakeApp(); @@ -625,44 +564,52 @@ export class Iterable { } if (Iterable.savedConfig.customActionHandler) { - RNEventEmitter.addListener(EventName.handleCustomActionCalled, (dict) => { - const action = IterableAction.fromDict(dict.action); - const context = IterableActionContext.fromDict(dict.context); - Iterable.savedConfig.customActionHandler!(action, context); - }); + RNEventEmitter.addListener( + IterableEventName.handleCustomActionCalled, + (dict) => { + const action = IterableAction.fromDict(dict.action); + const context = IterableActionContext.fromDict(dict.context); + Iterable.savedConfig.customActionHandler!(action, context); + } + ); } if (Iterable.savedConfig.inAppHandler) { - RNEventEmitter.addListener(EventName.handleInAppCalled, (messageDict) => { - const message = IterableInAppMessage.fromDict(messageDict); - const result = Iterable.savedConfig.inAppHandler!(message); - RNIterableAPI.setInAppShowResponse(result); - }); + RNEventEmitter.addListener( + IterableEventName.handleInAppCalled, + (messageDict) => { + const message = IterableInAppMessage.fromDict(messageDict); + const result = Iterable.savedConfig.inAppHandler!(message); + RNIterableAPI.setInAppShowResponse(result); + } + ); } if (Iterable.savedConfig.authHandler) { - let authResponseCallback: AuthResponseCallback; - RNEventEmitter.addListener(EventName.handleAuthCalled, () => { + let authResponseCallback: IterableAuthResponseResult; + RNEventEmitter.addListener(IterableEventName.handleAuthCalled, () => { Iterable.savedConfig.authHandler!() .then((promiseResult) => { // Promise result can be either just String OR of type AuthResponse. // If type AuthReponse, authToken will be parsed looking for `authToken` within promised object. Two additional listeners will be registered for success and failure callbacks sent by native bridge layer. // Else it will be looked for as a String. - if (typeof promiseResult === typeof new AuthResponse()) { + if (typeof promiseResult === typeof new IterableAuthResponse()) { RNIterableAPI.passAlongAuthToken( - (promiseResult as AuthResponse).authToken + (promiseResult as IterableAuthResponse).authToken ); setTimeout(() => { - if (authResponseCallback === AuthResponseCallback.SUCCESS) { - if ((promiseResult as AuthResponse).successCallback) { - (promiseResult as AuthResponse).successCallback!(); + if ( + authResponseCallback === IterableAuthResponseResult.SUCCESS + ) { + if ((promiseResult as IterableAuthResponse).successCallback) { + (promiseResult as IterableAuthResponse).successCallback!(); } } else if ( - authResponseCallback === AuthResponseCallback.FAILURE + authResponseCallback === IterableAuthResponseResult.FAILURE ) { - if ((promiseResult as AuthResponse).failureCallback) { - (promiseResult as AuthResponse).failureCallback!(); + if ((promiseResult as IterableAuthResponse).failureCallback) { + (promiseResult as IterableAuthResponse).failureCallback!(); } } else { Iterable.logger.log('No callback received from native layer'); @@ -680,12 +627,18 @@ export class Iterable { .catch((e) => Iterable.logger.log(e)); }); - RNEventEmitter.addListener(EventName.handleAuthSuccessCalled, () => { - authResponseCallback = AuthResponseCallback.SUCCESS; - }); - RNEventEmitter.addListener(EventName.handleAuthFailureCalled, () => { - authResponseCallback = AuthResponseCallback.FAILURE; - }); + RNEventEmitter.addListener( + IterableEventName.handleAuthSuccessCalled, + () => { + authResponseCallback = IterableAuthResponseResult.SUCCESS; + } + ); + RNEventEmitter.addListener( + IterableEventName.handleAuthFailureCalled, + () => { + authResponseCallback = IterableAuthResponseResult.FAILURE; + } + ); } function callUrlHandler(url: any, context: IterableActionContext) { @@ -706,10 +659,8 @@ export class Iterable { } private static getVersionFromPackageJson(): string { - const json = require('../package.json'); + const json = require('../../../package.json'); const version = json.version as string; return version; } } - -export default Iterable; diff --git a/src/core/classes/IterableAction.ts b/src/core/classes/IterableAction.ts new file mode 100644 index 000000000..b325487ae --- /dev/null +++ b/src/core/classes/IterableAction.ts @@ -0,0 +1,19 @@ +/** + * IterableAction represents an action defined as a response to user events. + * It is currently used in push notification actions (open push & action buttons). + */ +export class IterableAction { + type: string; + data?: string; + userInput?: string; + + constructor(type: string, data?: string, userInput?: string) { + this.type = type; + this.data = data; + this.userInput = userInput; + } + + static fromDict(dict: any): IterableAction { + return new IterableAction(dict.type, dict.data, dict.userInput); + } +} diff --git a/src/core/classes/IterableActionContext.ts b/src/core/classes/IterableActionContext.ts new file mode 100644 index 000000000..64581e7fd --- /dev/null +++ b/src/core/classes/IterableActionContext.ts @@ -0,0 +1,21 @@ +import type { IterableActionSource } from '../enums'; +import { IterableAction } from './IterableAction'; + +/** + * TODO: Add description + */ +export class IterableActionContext { + action: IterableAction; + source: IterableActionSource; + + constructor(action: IterableAction, source: IterableActionSource) { + this.action = action; + this.source = source; + } + + static fromDict(dict: any): IterableActionContext { + const action = IterableAction.fromDict(dict.action); + const source = dict.source as IterableActionSource; + return new IterableActionContext(action, source); + } +} diff --git a/src/core/classes/IterableAttributionInfo.ts b/src/core/classes/IterableAttributionInfo.ts new file mode 100644 index 000000000..5b8a1929a --- /dev/null +++ b/src/core/classes/IterableAttributionInfo.ts @@ -0,0 +1,14 @@ +/** + * TODO: Add description + */ +export class IterableAttributionInfo { + campaignId: number; + templateId: number; + messageId: string; + + constructor(campaignId: number, templateId: number, messageId: string) { + this.campaignId = campaignId; + this.templateId = templateId; + this.messageId = messageId; + } +} diff --git a/src/core/classes/IterableAuthResponse.ts b/src/core/classes/IterableAuthResponse.ts new file mode 100644 index 000000000..716b52b73 --- /dev/null +++ b/src/core/classes/IterableAuthResponse.ts @@ -0,0 +1,8 @@ +// TODO: Add comments and descriptions +// REVIEW: This seems to currently be used as a type instead of a class, so it +// might be better to make it a type +export class IterableAuthResponse { + authToken?: string = ''; + successCallback?: () => void; + failureCallback?: () => void; +} diff --git a/src/core/classes/IterableCommerceItem.ts b/src/core/classes/IterableCommerceItem.ts new file mode 100644 index 000000000..8cbcaad39 --- /dev/null +++ b/src/core/classes/IterableCommerceItem.ts @@ -0,0 +1,39 @@ +/** + * TODO: Add description + */ +export class IterableCommerceItem { + id: string; + name: string; + price: number; + quantity: number; + sku?: string; + description?: string; + url?: string; + imageUrl?: string; + categories?: Array; + dataFields?: any; + + constructor( + id: string, + name: string, + price: number, + quantity: number, + sku?: string, + description?: string, + url?: string, + imageUrl?: string, + categories?: Array, + dataFields?: any | undefined + ) { + this.id = id; + this.name = name; + this.price = price; + this.quantity = quantity; + this.sku = sku; + this.description = description; + this.url = url; + this.imageUrl = imageUrl; + this.categories = categories; + this.dataFields = dataFields; + } +} diff --git a/src/IterableConfig.ts b/src/core/classes/IterableConfig.ts similarity index 91% rename from src/IterableConfig.ts rename to src/core/classes/IterableConfig.ts index ce17b5c7f..be678e3d8 100644 --- a/src/IterableConfig.ts +++ b/src/core/classes/IterableConfig.ts @@ -1,15 +1,12 @@ +import { IterableInAppMessage, IterableInAppShowResponse } from '../../inApp'; import { - IterableAction, - IterableActionContext, + IterableDataRegion, IterableLogLevel, -} from './IterableAction'; -import { IterableDataRegion } from './IterableDataRegion'; -import { IterableInAppShowResponse } from './IterableInAppClasses'; -import { IterableInAppMessage } from './IterableInAppMessage'; -import { IterablePushPlatform } from './IterablePushPlatform'; - -// TODO: Add description -type AuthCallBack = () => void; + IterablePushPlatform, +} from '../enums'; +import { IterableAction } from './IterableAction'; +import type { IterableActionContext } from './IterableActionContext'; +import type { IterableAuthResponse } from './IterableAuthResponse'; /** * An IterableConfig object sets various properties of the SDK. @@ -72,7 +69,7 @@ export class IterableConfig { * React Native SDK. Provide an implementation for this method only if your app uses a * JWT-enabled API key. */ - authHandler?: () => Promise; + authHandler?: () => Promise; /** * Set the verbosity of Android and iOS project's log system. @@ -164,10 +161,3 @@ export class IterableConfig { }; } } - -// TODO: Add comments and descriptions -export class AuthResponse { - authToken?: string = ''; - successCallback?: AuthCallBack; - failureCallback?: AuthCallBack; -} diff --git a/src/core/classes/IterableEdgeInsets.ts b/src/core/classes/IterableEdgeInsets.ts new file mode 100644 index 000000000..dd3da9749 --- /dev/null +++ b/src/core/classes/IterableEdgeInsets.ts @@ -0,0 +1,23 @@ +// TODO: Add description +export class IterableEdgeInsets { + top: number; + left: number; + bottom: number; + right: number; + + constructor(top: number, left: number, bottom: number, right: number) { + this.top = top; + this.left = left; + this.bottom = bottom; + this.right = right; + } + + static fromDict(dict: any): IterableEdgeInsets { + return new IterableEdgeInsets( + dict.top as number, + dict.left as number, + dict.bottom as number, + dict.right as number + ); + } +} diff --git a/src/IterableLogger.ts b/src/core/classes/IterableLogger.ts similarity index 100% rename from src/IterableLogger.ts rename to src/core/classes/IterableLogger.ts diff --git a/src/IterableUtil.ts b/src/core/classes/IterableUtil.ts similarity index 79% rename from src/IterableUtil.ts rename to src/core/classes/IterableUtil.ts index e160ce607..b30b2935a 100644 --- a/src/IterableUtil.ts +++ b/src/core/classes/IterableUtil.ts @@ -1,4 +1,5 @@ // TODO: Add a description +// TODO: Change to a util function instead of a class export class IterableUtil { static readBoolean(dict: any, key: string): boolean { if (dict[key]) { diff --git a/src/core/classes/index.ts b/src/core/classes/index.ts new file mode 100644 index 000000000..60c26047c --- /dev/null +++ b/src/core/classes/index.ts @@ -0,0 +1,10 @@ +export * from './Iterable'; +export * from './IterableAction'; +export * from './IterableActionContext'; +export * from './IterableAttributionInfo'; +export * from './IterableAuthResponse'; +export * from './IterableCommerceItem'; +export * from './IterableConfig'; +export * from './IterableEdgeInsets'; +export * from './IterableLogger'; +export * from './IterableUtil'; diff --git a/src/core/enums/IterableActionSource.ts b/src/core/enums/IterableActionSource.ts new file mode 100644 index 000000000..2cecfcf02 --- /dev/null +++ b/src/core/enums/IterableActionSource.ts @@ -0,0 +1,8 @@ +/** + * Enum representing the source of IterableAction. + */ +export enum IterableActionSource { + push = 0, + appLink = 1, + inApp = 2, +} diff --git a/src/core/enums/IterableAuthResponseResult.ts b/src/core/enums/IterableAuthResponseResult.ts new file mode 100644 index 000000000..03fb6a30a --- /dev/null +++ b/src/core/enums/IterableAuthResponseResult.ts @@ -0,0 +1,5 @@ +// TODO: Add description +export enum IterableAuthResponseResult { + SUCCESS, + FAILURE, +} diff --git a/src/IterableDataRegion.ts b/src/core/enums/IterableDataRegion.ts similarity index 100% rename from src/IterableDataRegion.ts rename to src/core/enums/IterableDataRegion.ts diff --git a/src/core/enums/IterableEventName.ts b/src/core/enums/IterableEventName.ts new file mode 100644 index 000000000..648032f05 --- /dev/null +++ b/src/core/enums/IterableEventName.ts @@ -0,0 +1,10 @@ +// TODO: Add description +export enum IterableEventName { + handleUrlCalled = 'handleUrlCalled', + handleCustomActionCalled = 'handleCustomActionCalled', + handleInAppCalled = 'handleInAppCalled', + handleAuthCalled = 'handleAuthCalled', + receivedIterableInboxChanged = 'receivedIterableInboxChanged', + handleAuthSuccessCalled = 'handleAuthSuccessCalled', + handleAuthFailureCalled = 'handleAuthFailureCalled', +} diff --git a/src/core/enums/IterableLogLevel.ts b/src/core/enums/IterableLogLevel.ts new file mode 100644 index 000000000..11675183b --- /dev/null +++ b/src/core/enums/IterableLogLevel.ts @@ -0,0 +1,8 @@ +/** + * Enum representing what level of logs will Android and iOS project be printing on their consoles respectively. + */ +export enum IterableLogLevel { + debug = 1, + info = 2, + error = 3, +} diff --git a/src/IterablePushPlatform.ts b/src/core/enums/IterablePushPlatform.ts similarity index 77% rename from src/IterablePushPlatform.ts rename to src/core/enums/IterablePushPlatform.ts index 0375c3768..fbe88b871 100644 --- a/src/IterablePushPlatform.ts +++ b/src/core/enums/IterablePushPlatform.ts @@ -1,3 +1,4 @@ +// TODO: add decription export enum IterablePushPlatform { sandbox = 0, production = 1, diff --git a/src/core/enums/index.ts b/src/core/enums/index.ts new file mode 100644 index 000000000..e95b5350c --- /dev/null +++ b/src/core/enums/index.ts @@ -0,0 +1,6 @@ +export * from './IterableActionSource'; +export * from './IterableAuthResponseResult'; +export * from './IterableDataRegion'; +export * from './IterableEventName'; +export * from './IterableLogLevel'; +export * from './IterablePushPlatform'; diff --git a/src/core/hooks/index.ts b/src/core/hooks/index.ts new file mode 100644 index 000000000..35d77007a --- /dev/null +++ b/src/core/hooks/index.ts @@ -0,0 +1,2 @@ +export * from './useAppStateListener'; +export * from './useDeviceOrientation'; diff --git a/src/useAppStateListener.ts b/src/core/hooks/useAppStateListener.ts similarity index 100% rename from src/useAppStateListener.ts rename to src/core/hooks/useAppStateListener.ts diff --git a/src/useDeviceOrientation.tsx b/src/core/hooks/useDeviceOrientation.tsx similarity index 100% rename from src/useDeviceOrientation.tsx rename to src/core/hooks/useDeviceOrientation.tsx diff --git a/src/core/index.ts b/src/core/index.ts new file mode 100644 index 000000000..731284104 --- /dev/null +++ b/src/core/index.ts @@ -0,0 +1,3 @@ +export * from './classes'; +export * from './enums'; +export * from './hooks'; diff --git a/src/inApp/classes/IterableHtmlInAppContent.ts b/src/inApp/classes/IterableHtmlInAppContent.ts new file mode 100644 index 000000000..6e156eec2 --- /dev/null +++ b/src/inApp/classes/IterableHtmlInAppContent.ts @@ -0,0 +1,23 @@ +import { IterableEdgeInsets } from '../../core'; + +import { IterableInAppContentType } from '../enums'; +import type { IterableInAppContent } from '../types'; + +// TODO: Add description +export class IterableHtmlInAppContent implements IterableInAppContent { + type: IterableInAppContentType = IterableInAppContentType.html; + edgeInsets: IterableEdgeInsets; + html: string; + + constructor(edgeInsets: IterableEdgeInsets, html: string) { + this.edgeInsets = edgeInsets; + this.html = html; + } + + static fromDict(dict: any): IterableHtmlInAppContent { + return new IterableHtmlInAppContent( + IterableEdgeInsets.fromDict(dict.edgeInsets), + dict.html as string + ); + } +} diff --git a/src/IterableInAppManager.ts b/src/inApp/classes/IterableInAppManager.ts similarity index 97% rename from src/IterableInAppManager.ts rename to src/inApp/classes/IterableInAppManager.ts index f7370b78c..7ec2482fd 100644 --- a/src/IterableInAppManager.ts +++ b/src/inApp/classes/IterableInAppManager.ts @@ -1,11 +1,11 @@ import { NativeModules } from 'react-native'; -import { Iterable } from './Iterable'; -import { - IterableHtmlInAppContent, +import { Iterable } from '../../core'; +import type { IterableInAppDeleteSource, IterableInAppLocation, -} from './IterableInAppClasses'; +} from '../enums'; +import { IterableHtmlInAppContent } from './IterableHtmlInAppContent'; import { IterableInAppMessage } from './IterableInAppMessage'; // TODO: Create a loader for this diff --git a/src/IterableInAppMessage.ts b/src/inApp/classes/IterableInAppMessage.ts similarity index 94% rename from src/IterableInAppMessage.ts rename to src/inApp/classes/IterableInAppMessage.ts index fb3030319..fbf91b1ef 100644 --- a/src/IterableInAppMessage.ts +++ b/src/inApp/classes/IterableInAppMessage.ts @@ -1,12 +1,9 @@ import { type ViewToken } from 'react-native'; -import { IterableUtil } from './IterableUtil'; - -import { - IterableInAppTrigger, - IterableInAppTriggerType, - IterableInboxMetadata, -} from './IterableInAppClasses'; +import { IterableUtil } from '../../core'; +import { IterableInAppTriggerType } from '../enums'; +import { IterableInAppTrigger } from './IterableInAppTrigger'; +import { IterableInboxMetadata } from './IterableInboxMetadata'; /** * Iterable in-app message diff --git a/src/inApp/classes/IterableInAppTrigger.ts b/src/inApp/classes/IterableInAppTrigger.ts new file mode 100644 index 000000000..1737bfdf7 --- /dev/null +++ b/src/inApp/classes/IterableInAppTrigger.ts @@ -0,0 +1,17 @@ +import type { IterableInAppTriggerType } from '../enums'; + +// TODO: Add description +export class IterableInAppTrigger { + type: IterableInAppTriggerType; + + constructor(type: IterableInAppTriggerType) { + this.type = type; + } + + static fromDict(dict: any): IterableInAppTrigger { + const type = dict.type as + | IterableInAppTriggerType + | IterableInAppTriggerType.immediate; + return new IterableInAppTrigger(type); + } +} diff --git a/src/inApp/classes/IterableInboxMetadata.ts b/src/inApp/classes/IterableInboxMetadata.ts new file mode 100644 index 000000000..517cb7fc8 --- /dev/null +++ b/src/inApp/classes/IterableInboxMetadata.ts @@ -0,0 +1,22 @@ +/** + * TODO: Add description + */ +export class IterableInboxMetadata { + title?: string; + subtitle?: string; + icon?: string; + + constructor( + title: string | undefined, + subtitle: string | undefined, + icon: string | undefined + ) { + this.title = title; + this.subtitle = subtitle; + this.icon = icon; + } + + static fromDict(dict: any): IterableInboxMetadata { + return new IterableInboxMetadata(dict.title, dict.subtitle, dict.icon); + } +} diff --git a/src/inApp/classes/index.ts b/src/inApp/classes/index.ts new file mode 100644 index 000000000..ae4f861ae --- /dev/null +++ b/src/inApp/classes/index.ts @@ -0,0 +1,5 @@ +export * from './IterableHtmlInAppContent'; +export * from './IterableInAppManager'; +export * from './IterableInAppMessage'; +export * from './IterableInAppTrigger'; +export * from './IterableInboxMetadata'; diff --git a/src/inApp/enums/IterableInAppCloseSource.ts b/src/inApp/enums/IterableInAppCloseSource.ts new file mode 100644 index 000000000..ebd780cec --- /dev/null +++ b/src/inApp/enums/IterableInAppCloseSource.ts @@ -0,0 +1,6 @@ +// TODO: Add description +export enum IterableInAppCloseSource { + back = 0, + link = 1, + unknown = 100, +} diff --git a/src/inApp/enums/IterableInAppContentType.ts b/src/inApp/enums/IterableInAppContentType.ts new file mode 100644 index 000000000..4210a8603 --- /dev/null +++ b/src/inApp/enums/IterableInAppContentType.ts @@ -0,0 +1,6 @@ +// TODO: Add description +export enum IterableInAppContentType { + html = 0, + alert = 1, + banner = 2, +} diff --git a/src/inApp/enums/IterableInAppDeleteSource.ts b/src/inApp/enums/IterableInAppDeleteSource.ts new file mode 100644 index 000000000..10ae58f5c --- /dev/null +++ b/src/inApp/enums/IterableInAppDeleteSource.ts @@ -0,0 +1,6 @@ +// TODO: Add description +export enum IterableInAppDeleteSource { + inboxSwipe = 0, + deleteButton = 1, + unknown = 100, +} diff --git a/src/inApp/enums/IterableInAppLocation.ts b/src/inApp/enums/IterableInAppLocation.ts new file mode 100644 index 000000000..bca7fb8db --- /dev/null +++ b/src/inApp/enums/IterableInAppLocation.ts @@ -0,0 +1,5 @@ +// TODO: Add description +export enum IterableInAppLocation { + inApp = 0, + inbox = 1, +} diff --git a/src/inApp/enums/IterableInAppShowResponse.ts b/src/inApp/enums/IterableInAppShowResponse.ts new file mode 100644 index 000000000..a6137e2fd --- /dev/null +++ b/src/inApp/enums/IterableInAppShowResponse.ts @@ -0,0 +1,7 @@ +// TODO: Add description +export enum IterableInAppShowResponse { + /** Show in-app */ + show = 0, + /** Skip showing in-app */ + skip = 1, +} diff --git a/src/inApp/enums/IterableInAppTriggerType.ts b/src/inApp/enums/IterableInAppTriggerType.ts new file mode 100644 index 000000000..4f1719a74 --- /dev/null +++ b/src/inApp/enums/IterableInAppTriggerType.ts @@ -0,0 +1,9 @@ +// TODO: Add description +export enum IterableInAppTriggerType { + /** Tries to display the in-app automatically immediately */ + immediate = 0, + /** Used for Push to in-app */ + event = 1, + /** Do not display the in-app automatically via the SDK */ + never = 2, +} diff --git a/src/inApp/enums/index.ts b/src/inApp/enums/index.ts new file mode 100644 index 000000000..10769e440 --- /dev/null +++ b/src/inApp/enums/index.ts @@ -0,0 +1,6 @@ +export * from './IterableInAppShowResponse'; +export * from './IterableInAppTriggerType'; +export * from './IterableInAppContentType'; +export * from './IterableInAppLocation'; +export * from './IterableInAppDeleteSource'; +export * from './IterableInAppCloseSource'; diff --git a/src/inApp/index.ts b/src/inApp/index.ts new file mode 100644 index 000000000..38c539f76 --- /dev/null +++ b/src/inApp/index.ts @@ -0,0 +1,3 @@ +export * from './classes'; +export * from './enums'; +export * from './types'; diff --git a/src/inApp/types/IterableInAppContent.ts b/src/inApp/types/IterableInAppContent.ts new file mode 100644 index 000000000..a2a312e58 --- /dev/null +++ b/src/inApp/types/IterableInAppContent.ts @@ -0,0 +1,6 @@ +import type { IterableInAppContentType } from '../enums'; + +// TODO: Add description +export interface IterableInAppContent { + type: IterableInAppContentType; +} diff --git a/src/inApp/types/index.ts b/src/inApp/types/index.ts new file mode 100644 index 000000000..bd83b3125 --- /dev/null +++ b/src/inApp/types/index.ts @@ -0,0 +1 @@ +export * from './IterableInAppContent'; diff --git a/src/IterableInboxDataModel.ts b/src/inbox/classes/IterableInboxDataModel.ts similarity index 88% rename from src/IterableInboxDataModel.ts rename to src/inbox/classes/IterableInboxDataModel.ts index 29dce8e1a..d2456ed9c 100644 --- a/src/IterableInboxDataModel.ts +++ b/src/inbox/classes/IterableInboxDataModel.ts @@ -1,15 +1,16 @@ import { NativeModules } from 'react-native'; + +import { Iterable } from '../../core'; import { IterableHtmlInAppContent, IterableInAppDeleteSource, IterableInAppLocation, -} from './IterableInAppClasses'; - -import { Iterable } from './Iterable'; - -import type { InboxImpressionRowInfo } from './InboxImpressionRowInfo'; -import type { InboxRowViewModel } from './InboxRowViewModel'; -import { IterableInAppMessage } from './IterableInAppMessage'; + IterableInAppMessage, +} from '../../inApp'; +import type { + IterableInboxImpressionRowInfo, + IterableInboxRowViewModel, +} from '../types'; const RNIterableAPI = NativeModules.RNIterableAPI; @@ -73,7 +74,7 @@ export class IterableInboxDataModel { RNIterableAPI.removeMessage(id, IterableInAppLocation.inbox, deleteSource); } - async refresh(): Promise> { + async refresh(): Promise> { return RNIterableAPI.getInboxMessages().then( (messages: Array) => { return this.processMessages(messages); @@ -86,16 +87,16 @@ export class IterableInboxDataModel { // inbox session tracking functions - startSession(visibleRows: Array = []) { + startSession(visibleRows: Array = []) { RNIterableAPI.startSession(visibleRows); } - async endSession(visibleRows: Array = []) { + async endSession(visibleRows: Array = []) { await this.updateVisibleRows(visibleRows); RNIterableAPI.endSession(); } - updateVisibleRows(visibleRows: Array = []) { + updateVisibleRows(visibleRows: Array = []) { RNIterableAPI.updateVisibleRows(visibleRows); } @@ -134,7 +135,7 @@ export class IterableInboxDataModel { private processMessages( messages: Array - ): Array { + ): Array { return this.sortAndFilter(messages).map( IterableInboxDataModel.getInboxRowViewModelForMessage ); @@ -164,7 +165,7 @@ export class IterableInboxDataModel { private static getInboxRowViewModelForMessage( message: IterableInAppMessage - ): InboxRowViewModel { + ): IterableInboxRowViewModel { return { title: message.inboxMetadata?.title ?? '', subtitle: message.inboxMetadata?.subtitle, diff --git a/src/inbox/classes/index.ts b/src/inbox/classes/index.ts new file mode 100644 index 000000000..52c9b2a70 --- /dev/null +++ b/src/inbox/classes/index.ts @@ -0,0 +1 @@ +export * from './IterableInboxDataModel'; diff --git a/src/IterableInbox.tsx b/src/inbox/components/IterableInbox.tsx similarity index 92% rename from src/IterableInbox.tsx rename to src/inbox/components/IterableInbox.tsx index decab4a7a..b60caa773 100644 --- a/src/IterableInbox.tsx +++ b/src/inbox/components/IterableInbox.tsx @@ -11,20 +11,22 @@ import { } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; -import type { InboxImpressionRowInfo } from './InboxImpressionRowInfo'; -import type { InboxRowViewModel } from './InboxRowViewModel'; -import { Iterable } from './Iterable'; import { - IterableInAppDeleteSource, - IterableInAppLocation, -} from './IterableInAppClasses'; -import type { IterableInboxCustomizations } from './IterableInboxCustomizations'; -import { IterableInboxDataModel } from './IterableInboxDataModel'; + Iterable, + useAppStateListener, + useDeviceOrientation, +} from '../../core'; +import { IterableInAppDeleteSource, IterableInAppLocation } from '../../inApp'; + +import { IterableInboxDataModel } from '../classes'; +import type { + IterableInboxCustomizations, + IterableInboxImpressionRowInfo, + IterableInboxRowViewModel, +} from '../types'; import { IterableInboxEmptyState } from './IterableInboxEmptyState'; import { IterableInboxMessageDisplay } from './IterableInboxMessageDisplay'; import { IterableInboxMessageList } from './IterableInboxMessageList'; -import { useAppStateListener } from './useAppStateListener'; -import { useDeviceOrientation } from './useDeviceOrientation'; const RNIterableAPI = NativeModules.RNIterableAPI; const RNEventEmitter = new NativeEventEmitter(RNIterableAPI); @@ -59,13 +61,15 @@ export const IterableInbox = ({ const [selectedRowViewModelIdx, setSelectedRowViewModelIdx] = useState(0); - const [rowViewModels, setRowViewModels] = useState([]); + const [rowViewModels, setRowViewModels] = useState< + IterableInboxRowViewModel[] + >([]); const [loading, setLoading] = useState(true); const [animatedValue] = useState(new Animated.Value(0)); const [isMessageDisplay, setIsMessageDisplay] = useState(false); const [visibleMessageImpressions, setVisibleMessageImpressions] = useState< - InboxImpressionRowInfo[] + IterableInboxImpressionRowInfo[] >([]); const styles = StyleSheet.create({ @@ -202,7 +206,7 @@ export const IterableInbox = ({ function handleMessageSelect( id: string, index: number, - models: InboxRowViewModel[] + models: IterableInboxRowViewModel[] ) { let newRowViewModels = models.map((rowViewModel) => { return rowViewModel.inAppMessage.messageId === id @@ -241,13 +245,13 @@ export const IterableInbox = ({ } function updateVisibleMessageImpressions( - messageImpressions: InboxImpressionRowInfo[] + messageImpressions: IterableInboxImpressionRowInfo[] ) { setVisibleMessageImpressions(messageImpressions); } function showMessageDisplay( - rowViewModelList: InboxRowViewModel[], + rowViewModelList: IterableInboxRowViewModel[], index: number ) { const selectedRowViewModel = rowViewModelList[index]; @@ -287,7 +291,7 @@ export const IterableInbox = ({ handleMessageSelect(messageId, index, rowViewModels) } updateVisibleMessageImpressions={( - messageImpressions: InboxImpressionRowInfo[] + messageImpressions: IterableInboxImpressionRowInfo[] ) => updateVisibleMessageImpressions(messageImpressions)} contentWidth={width} isPortrait={isPortrait} diff --git a/src/IterableInboxEmptyState.tsx b/src/inbox/components/IterableInboxEmptyState.tsx similarity index 90% rename from src/IterableInboxEmptyState.tsx rename to src/inbox/components/IterableInboxEmptyState.tsx index 6e6c885ed..44b59d6a7 100644 --- a/src/IterableInboxEmptyState.tsx +++ b/src/inbox/components/IterableInboxEmptyState.tsx @@ -1,9 +1,9 @@ import { StyleSheet, Text, View } from 'react-native'; -import { type IterableInboxCustomizations } from './IterableInboxCustomizations'; +import { type IterableInboxCustomizations } from '../types'; // TODO: Comment -type EmptyStateProps = { +export interface IterableInboxEmptyStateProps { customizations: IterableInboxCustomizations; tabBarHeight: number; tabBarPadding: number; @@ -11,7 +11,7 @@ type EmptyStateProps = { contentWidth: number; height: number; isPortrait: boolean; -}; +} export const IterableInboxEmptyState = ({ customizations, @@ -20,7 +20,7 @@ export const IterableInboxEmptyState = ({ navTitleHeight, height, isPortrait, -}: EmptyStateProps) => { +}: IterableInboxEmptyStateProps) => { const defaultTitle = 'No saved messages'; const defaultBody = 'Check again later!'; diff --git a/src/IterableInboxMessageCell.tsx b/src/inbox/components/IterableInboxMessageCell.tsx similarity index 95% rename from src/IterableInboxMessageCell.tsx rename to src/inbox/components/IterableInboxMessageCell.tsx index d2489b2db..9b8c00d22 100644 --- a/src/IterableInboxMessageCell.tsx +++ b/src/inbox/components/IterableInboxMessageCell.tsx @@ -11,16 +11,17 @@ import { type ViewStyle, } from 'react-native'; -import type { InboxRowViewModel } from './InboxRowViewModel'; -import type { IterableInboxCustomizations } from './IterableInboxCustomizations'; - -import { IterableInboxDataModel } from './IterableInboxDataModel'; +import { IterableInboxDataModel } from '../classes'; +import type { + IterableInboxRowViewModel, + IterableInboxCustomizations, +} from '../types'; // TODO: Change to component function defaultMessageListLayout( last: boolean, dataModel: IterableInboxDataModel, - rowViewModel: InboxRowViewModel, + rowViewModel: IterableInboxRowViewModel, customizations: IterableInboxCustomizations, isPortrait: boolean ) { @@ -122,7 +123,7 @@ function defaultMessageListLayout( ? { ...messageContainer, width: '90%' } : messageContainer; - function messageRowStyle(_rowViewModel: InboxRowViewModel) { + function messageRowStyle(_rowViewModel: IterableInboxRowViewModel) { return last ? { ...messageRow, borderBottomWidth: 1 } : messageRow; } @@ -161,11 +162,11 @@ function defaultMessageListLayout( } // TODO: Comment -type MessageCellProps = { +export interface IterableInboxMessageCellProps { index: number; last: boolean; dataModel: IterableInboxDataModel; - rowViewModel: InboxRowViewModel; + rowViewModel: IterableInboxRowViewModel; customizations: IterableInboxCustomizations; swipingCheck: Function; messageListItemLayout: Function; @@ -173,7 +174,7 @@ type MessageCellProps = { handleMessageSelect: Function; contentWidth: number; isPortrait: boolean; -}; +} // TODO: Comment export const IterableInboxMessageCell = ({ @@ -188,7 +189,7 @@ export const IterableInboxMessageCell = ({ handleMessageSelect, contentWidth, isPortrait, -}: MessageCellProps) => { +}: IterableInboxMessageCellProps) => { const position = useRef(new Animated.ValueXY()).current; let deleteSliderHeight = customizations.messageRow?.height diff --git a/src/IterableInboxMessageDisplay.tsx b/src/inbox/components/IterableInboxMessageDisplay.tsx similarity index 95% rename from src/IterableInboxMessageDisplay.tsx rename to src/inbox/components/IterableInboxMessageDisplay.tsx index c89d79274..95f5256b5 100644 --- a/src/IterableInboxMessageDisplay.tsx +++ b/src/inbox/components/IterableInboxMessageDisplay.tsx @@ -10,29 +10,30 @@ import { import Icon from 'react-native-vector-icons/Ionicons'; import { WebView } from 'react-native-webview'; -import { type InboxRowViewModel } from './InboxRowViewModel'; -import { Iterable } from './Iterable'; import { + Iterable, IterableAction, IterableActionContext, IterableActionSource, -} from './IterableAction'; -import { IterableEdgeInsets, +} from '../../core'; +import { IterableHtmlInAppContent, IterableInAppCloseSource, IterableInAppLocation, -} from './IterableInAppClasses'; +} from '../../inApp'; + +import { type IterableInboxRowViewModel } from '../types'; // TODO: Comment -type MessageDisplayProps = { - rowViewModel: InboxRowViewModel; +export interface IterableInboxMessageDisplayProps { + rowViewModel: IterableInboxRowViewModel; inAppContentPromise: Promise; returnToInbox: Function; deleteRow: Function; contentWidth: number; isPortrait: boolean; -}; +} // TODO: Comment export const IterableInboxMessageDisplay = ({ @@ -42,7 +43,7 @@ export const IterableInboxMessageDisplay = ({ deleteRow, contentWidth, isPortrait, -}: MessageDisplayProps) => { +}: IterableInboxMessageDisplayProps) => { const messageTitle = rowViewModel.inAppMessage.inboxMetadata?.title; const [inAppContent, setInAppContent] = useState( new IterableHtmlInAppContent(new IterableEdgeInsets(0, 0, 0, 0), '') diff --git a/src/IterableInboxMessageList.tsx b/src/inbox/components/IterableInboxMessageList.tsx similarity index 81% rename from src/IterableInboxMessageList.tsx rename to src/inbox/components/IterableInboxMessageList.tsx index 2cd9d08a4..5baa39709 100644 --- a/src/IterableInboxMessageList.tsx +++ b/src/inbox/components/IterableInboxMessageList.tsx @@ -1,17 +1,20 @@ import { useCallback, useRef, useState } from 'react'; import { type ViewabilityConfig, type ViewToken, FlatList } from 'react-native'; -import type { InboxImpressionRowInfo } from './InboxImpressionRowInfo'; -import type { InboxRowViewModel } from './InboxRowViewModel'; -import { IterableInAppMessage } from './IterableInAppMessage'; -import type { IterableInboxCustomizations } from './IterableInboxCustomizations'; -import { IterableInboxDataModel } from './IterableInboxDataModel'; +import { IterableInAppMessage } from '../../inApp'; + +import { IterableInboxDataModel } from '../classes'; +import type { + IterableInboxImpressionRowInfo, + IterableInboxRowViewModel, + IterableInboxCustomizations, +} from '../types'; import { IterableInboxMessageCell } from './IterableInboxMessageCell'; // TODO: Comment -type MessageListProps = { +export interface IterableInboxMessageListProps { dataModel: IterableInboxDataModel; - rowViewModels: InboxRowViewModel[]; + rowViewModels: IterableInboxRowViewModel[]; customizations: IterableInboxCustomizations; messageListItemLayout: Function; deleteRow: Function; @@ -19,7 +22,7 @@ type MessageListProps = { updateVisibleMessageImpressions: Function; contentWidth: number; isPortrait: boolean; -}; +} // TODO: Comment export const IterableInboxMessageList = ({ @@ -32,12 +35,12 @@ export const IterableInboxMessageList = ({ updateVisibleMessageImpressions, contentWidth, isPortrait, -}: MessageListProps) => { +}: IterableInboxMessageListProps) => { const [swiping, setSwiping] = useState(false); const flatListRef = useRef(null); function renderRowViewModel( - rowViewModel: InboxRowViewModel, + rowViewModel: IterableInboxRowViewModel, index: number, last: boolean ) { @@ -61,14 +64,14 @@ export const IterableInboxMessageList = ({ function getRowInfosFromViewTokens( viewTokens: Array - ): Array { + ): Array { return viewTokens.map(function (viewToken) { const inAppMessage = IterableInAppMessage.fromViewToken(viewToken); const impression = { messageId: inAppMessage.messageId, silentInbox: inAppMessage.isSilentInbox(), - } as InboxImpressionRowInfo; + } as IterableInboxImpressionRowInfo; return impression; }); @@ -100,10 +103,12 @@ export const IterableInboxMessageList = ({ item, index, }: { - item: InboxRowViewModel; + item: IterableInboxRowViewModel; index: number; }) => renderRowViewModel(item, index, index === rowViewModels.length - 1)} - keyExtractor={(item: InboxRowViewModel) => item.inAppMessage.messageId} + keyExtractor={(item: IterableInboxRowViewModel) => + item.inAppMessage.messageId + } viewabilityConfig={inboxSessionViewabilityConfig} onViewableItemsChanged={inboxSessionItemsChanged} onLayout={() => { diff --git a/src/inbox/components/index.ts b/src/inbox/components/index.ts new file mode 100644 index 000000000..f00e88241 --- /dev/null +++ b/src/inbox/components/index.ts @@ -0,0 +1,5 @@ +export * from './IterableInbox'; +export * from './IterableInboxEmptyState'; +export * from './IterableInboxMessageCell'; +export * from './IterableInboxMessageDisplay'; +export * from './IterableInboxMessageList'; diff --git a/src/inbox/index.ts b/src/inbox/index.ts new file mode 100644 index 000000000..e8ff3a69b --- /dev/null +++ b/src/inbox/index.ts @@ -0,0 +1,3 @@ +export * from './classes'; +export * from './components'; +export * from './types'; diff --git a/src/IterableInboxCustomizations.ts b/src/inbox/types/IterableInboxCustomizations.ts similarity index 96% rename from src/IterableInboxCustomizations.ts rename to src/inbox/types/IterableInboxCustomizations.ts index 74ee52c35..17d621559 100644 --- a/src/IterableInboxCustomizations.ts +++ b/src/inbox/types/IterableInboxCustomizations.ts @@ -1,5 +1,5 @@ // TODO: Add description -export type IterableInboxCustomizations = { +export interface IterableInboxCustomizations { navTitle?: string; noMessagesTitle?: string; noMessagesBody?: string; @@ -66,4 +66,4 @@ export type IterableInboxCustomizations = { borderColor?: string; borderTopWidth?: number; }; -}; +} diff --git a/src/InboxImpressionRowInfo.ts b/src/inbox/types/IterableInboxImpressionRowInfo.ts similarity index 57% rename from src/InboxImpressionRowInfo.ts rename to src/inbox/types/IterableInboxImpressionRowInfo.ts index 5fa74fec6..29833ae00 100644 --- a/src/InboxImpressionRowInfo.ts +++ b/src/inbox/types/IterableInboxImpressionRowInfo.ts @@ -1,5 +1,5 @@ // TODO: Add description -export type InboxImpressionRowInfo = { +export interface IterableInboxImpressionRowInfo { messageId: string; silentInbox: boolean; -}; +} diff --git a/src/InboxRowViewModel.ts b/src/inbox/types/IterableInboxRowViewModel.ts similarity index 61% rename from src/InboxRowViewModel.ts rename to src/inbox/types/IterableInboxRowViewModel.ts index 966d8f95e..0c6e7f69d 100644 --- a/src/InboxRowViewModel.ts +++ b/src/inbox/types/IterableInboxRowViewModel.ts @@ -1,11 +1,11 @@ -import { IterableInAppMessage } from '.'; +import { IterableInAppMessage } from '../../inApp'; // TODO: Add description -export type InboxRowViewModel = { +export interface IterableInboxRowViewModel { title: string; subtitle?: string; imageUrl?: string; createdAt?: Date; read: boolean; inAppMessage: IterableInAppMessage; -}; +} diff --git a/src/inbox/types/index.ts b/src/inbox/types/index.ts new file mode 100644 index 000000000..2cc9a9510 --- /dev/null +++ b/src/inbox/types/index.ts @@ -0,0 +1,3 @@ +export * from './IterableInboxImpressionRowInfo'; +export * from './IterableInboxCustomizations'; +export * from './IterableInboxRowViewModel'; diff --git a/src/index.tsx b/src/index.tsx index b40df9825..48cd7e669 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -2,39 +2,42 @@ * React Native module for Iterable. * @module react-native-iterable-sdk */ -export type { InboxImpressionRowInfo } from './InboxImpressionRowInfo'; -export type { InboxRowViewModel } from './InboxRowViewModel'; export { Iterable, + IterableAction, + IterableActionContext, IterableAttributionInfo, IterableCommerceItem, -} from './Iterable'; + IterableConfig, + IterableEdgeInsets, +} from './core/classes'; export { - IterableAction, - IterableActionContext, IterableActionSource, + IterableDataRegion, + IterableEventName, IterableLogLevel, -} from './IterableAction'; -export { IterableConfig } from './IterableConfig'; -export { IterableDataRegion } from './IterableDataRegion'; +} from './core/enums'; +export { useAppStateListener, useDeviceOrientation } from './core/hooks'; export { - IterableEdgeInsets, IterableHtmlInAppContent, IterableInAppCloseSource, IterableInAppContentType, IterableInAppDeleteSource, IterableInAppLocation, + IterableInAppManager, + IterableInAppMessage, IterableInAppShowResponse, IterableInAppTrigger, IterableInAppTriggerType, IterableInboxMetadata, type IterableInAppContent, -} from './IterableInAppClasses'; -export { IterableInAppManager } from './IterableInAppManager'; -export { IterableInAppMessage } from './IterableInAppMessage'; -export { IterableInbox, type IterableInboxProps } from './IterableInbox'; -export type { IterableInboxCustomizations } from './IterableInboxCustomizations'; -export { IterableInboxEmptyState } from './IterableInboxEmptyState'; -export { IterableInboxMessageCell } from './IterableInboxMessageCell'; -export { useAppStateListener } from './useAppStateListener'; -export { useDeviceOrientation } from './useDeviceOrientation'; +} from './inApp'; +export { + IterableInbox, + IterableInboxEmptyState, + IterableInboxMessageCell, + type IterableInboxImpressionRowInfo as InboxImpressionRowInfo, + type IterableInboxRowViewModel as InboxRowViewModel, + type IterableInboxCustomizations, + type IterableInboxProps, +} from './inbox';