@adapty/capacitor 3.12.0-beta.1 → 3.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AdaptyCapacitor.podspec +3 -3
- package/Package.swift +1 -1
- package/README.md +24 -11
- package/android/build.gradle +4 -3
- package/android/src/main/kotlin/com/adapty/plugin/capacitor/AdaptyCapacitorImplementation.kt +2 -0
- package/dist/esm/adapty.d.ts +2 -1
- package/dist/esm/adapty.js +2 -2
- package/dist/esm/adapty.js.map +1 -1
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/shared/coders/adapty-configuration.js +12 -17
- package/dist/esm/shared/coders/adapty-configuration.js.map +1 -1
- package/dist/esm/shared/coders/adapty-purchase-result.js +3 -3
- package/dist/esm/shared/coders/adapty-purchase-result.js.map +1 -1
- package/dist/esm/shared/coders/adapty-ui-create-onboarding-view-params.d.ts +8 -0
- package/dist/esm/shared/coders/adapty-ui-create-onboarding-view-params.js +10 -0
- package/dist/esm/shared/coders/adapty-ui-create-onboarding-view-params.js.map +1 -0
- package/dist/esm/shared/coders/adapty-ui-create-paywall-view-params.d.ts +18 -0
- package/dist/esm/shared/coders/adapty-ui-create-paywall-view-params.js +142 -0
- package/dist/esm/shared/coders/adapty-ui-create-paywall-view-params.js.map +1 -0
- package/dist/esm/shared/coders/parse-onboarding.d.ts +3 -0
- package/dist/esm/shared/coders/parse-onboarding.js +86 -0
- package/dist/esm/shared/coders/parse-onboarding.js.map +1 -0
- package/dist/esm/shared/coders/parse-paywall.d.ts +4 -0
- package/dist/esm/shared/coders/parse-paywall.js +141 -0
- package/dist/esm/shared/coders/parse-paywall.js.map +1 -0
- package/dist/esm/shared/coders/parse.d.ts +0 -2
- package/dist/esm/shared/coders/parse.js +0 -75
- package/dist/esm/shared/coders/parse.js.map +1 -1
- package/dist/esm/shared/coders/utils.d.ts +18 -0
- package/dist/esm/shared/coders/utils.js +50 -0
- package/dist/esm/shared/coders/utils.js.map +1 -0
- package/dist/esm/shared/types/index.d.ts +6 -0
- package/dist/esm/shared/types/index.js +5 -0
- package/dist/esm/shared/types/index.js.map +1 -1
- package/dist/esm/shared/types/inputs.d.ts +12 -4
- package/dist/esm/shared/types/inputs.js.map +1 -1
- package/dist/esm/shared/types/onboarding-events.d.ts +60 -0
- package/dist/esm/shared/types/onboarding-events.js +11 -0
- package/dist/esm/shared/types/onboarding-events.js.map +1 -0
- package/dist/esm/shared/types/paywall-events.d.ts +84 -0
- package/dist/esm/shared/types/paywall-events.js +16 -0
- package/dist/esm/shared/types/paywall-events.js.map +1 -0
- package/dist/esm/types/adapty-plugin.d.ts +2 -1
- package/dist/esm/types/adapty-plugin.js.map +1 -1
- package/dist/esm/ui-builder/base-view-emitter.d.ts +14 -20
- package/dist/esm/ui-builder/base-view-emitter.js +95 -73
- package/dist/esm/ui-builder/base-view-emitter.js.map +1 -1
- package/dist/esm/ui-builder/create-onboarding-view.d.ts +32 -0
- package/dist/esm/ui-builder/create-onboarding-view.js +36 -0
- package/dist/esm/ui-builder/create-onboarding-view.js.map +1 -0
- package/dist/esm/ui-builder/create-paywall-view.d.ts +25 -0
- package/dist/esm/ui-builder/create-paywall-view.js +29 -0
- package/dist/esm/ui-builder/create-paywall-view.js.map +1 -0
- package/dist/esm/ui-builder/index.d.ts +6 -37
- package/dist/esm/ui-builder/index.js +4 -41
- package/dist/esm/ui-builder/index.js.map +1 -1
- package/dist/esm/ui-builder/onboarding-view-controller.d.ts +3 -2
- package/dist/esm/ui-builder/onboarding-view-controller.js +11 -6
- package/dist/esm/ui-builder/onboarding-view-controller.js.map +1 -1
- package/dist/esm/ui-builder/onboarding-view-emitter.d.ts +10 -24
- package/dist/esm/ui-builder/onboarding-view-emitter.js +49 -56
- package/dist/esm/ui-builder/onboarding-view-emitter.js.map +1 -1
- package/dist/esm/ui-builder/paywall-view-controller.d.ts +1 -0
- package/dist/esm/ui-builder/paywall-view-controller.js +12 -41
- package/dist/esm/ui-builder/paywall-view-controller.js.map +1 -1
- package/dist/esm/ui-builder/paywall-view-emitter.d.ts +8 -28
- package/dist/esm/ui-builder/paywall-view-emitter.js +86 -118
- package/dist/esm/ui-builder/paywall-view-emitter.js.map +1 -1
- package/dist/esm/ui-builder/types.d.ts +84 -4
- package/dist/esm/ui-builder/types.js +3 -3
- package/dist/esm/ui-builder/types.js.map +1 -1
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/version.js.map +1 -1
- package/dist/plugin.cjs.js +938 -594
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +938 -594
- package/dist/plugin.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Adapty } from '../adapty';
|
|
2
2
|
import type { AdaptyOnboarding } from '../shared/types';
|
|
3
|
-
import type { OnboardingEventHandlers, AdaptyIOSPresentationStyle } from './types';
|
|
3
|
+
import type { OnboardingEventHandlers, AdaptyIOSPresentationStyle, CreateOnboardingViewParamsInput } from './types';
|
|
4
|
+
export declare const DEFAULT_ONBOARDING_PARAMS: CreateOnboardingViewParamsInput;
|
|
4
5
|
/**
|
|
5
6
|
* Controller for managing onboarding views.
|
|
6
7
|
*
|
|
@@ -21,7 +22,7 @@ export declare class OnboardingViewController {
|
|
|
21
22
|
* and creates reference between native controller and JS instance
|
|
22
23
|
* @internal
|
|
23
24
|
*/
|
|
24
|
-
static create(onboarding: AdaptyOnboarding, adaptyPlugin: Adapty): Promise<OnboardingViewController>;
|
|
25
|
+
static create(onboarding: AdaptyOnboarding, adaptyPlugin: Adapty, params?: CreateOnboardingViewParamsInput): Promise<OnboardingViewController>;
|
|
25
26
|
/**
|
|
26
27
|
* Since constructors in JS cannot be async, it is not
|
|
27
28
|
* preferred to create ViewControllers in direct way.
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { AdaptyError } from '../shared/adapty-error';
|
|
2
2
|
import { AdaptyOnboardingCoder } from '../shared/coders/adapty-onboarding';
|
|
3
|
+
import { AdaptyUICreateOnboardingViewParamsCoder } from '../shared/coders/adapty-ui-create-onboarding-view-params';
|
|
3
4
|
import { LogContext, Log } from '../shared/logger';
|
|
5
|
+
import { WebPresentation } from '../shared/types';
|
|
4
6
|
import { mapValues } from '../shared/utils/map-values';
|
|
5
7
|
import { withErrorContext } from '../shared/utils/with-error-context';
|
|
6
8
|
import { OnboardingViewEmitter } from './onboarding-view-emitter';
|
|
7
9
|
import { DEFAULT_ONBOARDING_EVENT_HANDLERS } from './types';
|
|
10
|
+
export const DEFAULT_ONBOARDING_PARAMS = {
|
|
11
|
+
externalUrlsPresentation: WebPresentation.BrowserInApp,
|
|
12
|
+
};
|
|
8
13
|
/**
|
|
9
14
|
* Controller for managing onboarding views.
|
|
10
15
|
*
|
|
@@ -22,17 +27,16 @@ export class OnboardingViewController {
|
|
|
22
27
|
* and creates reference between native controller and JS instance
|
|
23
28
|
* @internal
|
|
24
29
|
*/
|
|
25
|
-
static async create(onboarding, adaptyPlugin) {
|
|
30
|
+
static async create(onboarding, adaptyPlugin, params = {}) {
|
|
26
31
|
const controller = new OnboardingViewController(adaptyPlugin);
|
|
27
32
|
const ctx = new LogContext();
|
|
28
33
|
const methodKey = 'adapty_ui_create_onboarding_view';
|
|
29
34
|
const log = ctx.call({ methodName: methodKey });
|
|
30
|
-
log.start(() => ({ onboarding }));
|
|
35
|
+
log.start(() => ({ onboarding, params }));
|
|
31
36
|
const coder = new AdaptyOnboardingCoder();
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
};
|
|
37
|
+
const paramsWithDefaults = Object.assign(Object.assign({}, DEFAULT_ONBOARDING_PARAMS), params);
|
|
38
|
+
const encodedParams = new AdaptyUICreateOnboardingViewParamsCoder().encode(paramsWithDefaults);
|
|
39
|
+
const data = Object.assign({ method: methodKey, onboarding: coder.encode(onboarding) }, encodedParams);
|
|
36
40
|
const result = (await controller.adaptyPlugin.handleMethodCall(methodKey, JSON.stringify(data), ctx, log));
|
|
37
41
|
controller.id = result.id;
|
|
38
42
|
await controller.setEventHandlers(DEFAULT_ONBOARDING_EVENT_HANDLERS);
|
|
@@ -137,6 +141,7 @@ export class OnboardingViewController {
|
|
|
137
141
|
destroy: true,
|
|
138
142
|
};
|
|
139
143
|
await this.adaptyPlugin.handleMethodCall(methodKey, JSON.stringify(data), ctx, log);
|
|
144
|
+
this.clearEventHandlers();
|
|
140
145
|
}
|
|
141
146
|
/**
|
|
142
147
|
* Registers event handlers for onboarding UI events.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"onboarding-view-controller.js","sourceRoot":"","sources":["../../../src/ui-builder/onboarding-view-controller.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Adapty } from '../adapty';\nimport { AdaptyError } from '../shared/adapty-error';\nimport { AdaptyOnboardingCoder } from '../shared/coders/adapty-onboarding';\nimport { LogContext, Log } from '../shared/logger';\nimport type { AdaptyOnboarding } from '../shared/types';\nimport type { components } from '../shared/types/api';\nimport { mapValues } from '../shared/utils/map-values';\nimport { withErrorContext } from '../shared/utils/with-error-context';\n\nimport { OnboardingViewEmitter } from './onboarding-view-emitter';\nimport { DEFAULT_ONBOARDING_EVENT_HANDLERS } from './types';\nimport type { AdaptyUiView, OnboardingEventHandlers, AdaptyIOSPresentationStyle } from './types';\n\ntype Req = components['requests'];\n\n/**\n * Controller for managing onboarding views.\n *\n * @remarks\n * This class provides methods to present, dismiss, and handle events for onboarding views\n * created with the Onboarding Builder. Create instances using the {@link createOnboardingView} function\n * rather than directly constructing this class.\n *\n * @public\n */\nexport class OnboardingViewController {\n private id: string | null = null;\n private adaptyPlugin: Adapty;\n private viewEmitter: OnboardingViewEmitter | null = null;\n\n /**\n * Intended way to create a OnboardingViewController instance.\n * It prepares a native controller to be presented\n * and creates reference between native controller and JS instance\n * @internal\n */\n static async create(onboarding: AdaptyOnboarding, adaptyPlugin: Adapty): Promise<OnboardingViewController> {\n const controller = new OnboardingViewController(adaptyPlugin);\n\n const ctx = new LogContext();\n const methodKey = 'adapty_ui_create_onboarding_view';\n const log = ctx.call({ methodName: methodKey });\n log.start(() => ({ onboarding }));\n\n const coder = new AdaptyOnboardingCoder();\n const data: Req['AdaptyUICreateOnboardingView.Request'] = {\n method: methodKey,\n onboarding: coder.encode(onboarding),\n };\n\n const result = (await controller.adaptyPlugin.handleMethodCall(\n methodKey,\n JSON.stringify(data),\n ctx,\n log,\n )) as AdaptyUiView;\n controller.id = result.id;\n\n await controller.setEventHandlers(DEFAULT_ONBOARDING_EVENT_HANDLERS);\n\n return controller;\n }\n\n /**\n * Since constructors in JS cannot be async, it is not\n * preferred to create ViewControllers in direct way.\n * Consider using @link{OnboardingViewController.create} instead\n *\n * @internal\n */\n private constructor(adaptyPlugin: Adapty) {\n this.adaptyPlugin = adaptyPlugin;\n }\n\n /**\n * Presents the onboarding view as a modal screen.\n *\n * @remarks\n * Calling `present` on an already visible onboarding view will result in an error.\n * The onboarding will be displayed with the configured presentation style on iOS.\n * On Android, the onboarding is always presented as a full-screen activity.\n *\n * @param options - Optional presentation options\n * @param options.iosPresentationStyle - iOS presentation style. Available options: `'full_screen'` (default) or `'page_sheet'`. Only affects iOS platform.\n * @returns A promise that resolves when the onboarding is presented.\n * @throws {@link AdaptyError} if the view reference is invalid or the view is already presented.\n *\n * @example\n * Present with default full-screen style\n * ```typescript\n * import { adapty, createOnboardingView } from '@adapty/capacitor';\n *\n * const onboarding = await adapty.getOnboarding({ placementId: 'YOUR_PLACEMENT_ID' });\n * const view = await createOnboardingView(onboarding);\n * await view.present();\n * ```\n *\n * @example\n * Present with page sheet style on iOS\n * ```typescript\n * await view.present({ iosPresentationStyle: 'page_sheet' });\n * ```\n */\n public async present(options: { iosPresentationStyle?: AdaptyIOSPresentationStyle } = {}): Promise<void> {\n const ctx = new LogContext();\n const methodKey = 'adapty_ui_present_onboarding_view';\n const log = ctx.call({ methodName: methodKey });\n log.start(() => ({ _id: this.id, iosPresentationStyle: options.iosPresentationStyle }));\n\n if (this.id === null) {\n throw new AdaptyError({ adaptyCode: 2002, message: 'No view reference' });\n }\n\n const data: any = {\n method: methodKey,\n id: this.id,\n ios_presentation_style: options.iosPresentationStyle ?? 'full_screen',\n };\n\n await this.adaptyPlugin.handleMethodCall(methodKey, JSON.stringify(data), ctx, log);\n }\n\n /**\n * Dismisses the onboarding view.\n *\n * @remarks\n * This method closes the onboarding and cleans up associated resources.\n * After dismissing, the view controller instance cannot be reused.\n *\n * @returns A promise that resolves when the onboarding is dismissed.\n * @throws {@link AdaptyError} if the view reference is invalid.\n *\n * @example\n * ```typescript\n * import { createOnboardingView } from '@adapty/capacitor';\n *\n * const view = await createOnboardingView(onboarding);\n * await view.present();\n * // ... later\n * await view.dismiss();\n * ```\n */\n public async dismiss(): Promise<void> {\n const ctx = new LogContext();\n const methodKey = 'adapty_ui_dismiss_onboarding_view';\n const log = ctx.call({ methodName: methodKey });\n log.start(() => ({ _id: this.id }));\n\n if (this.id === null) {\n throw new AdaptyError({ adaptyCode: 2002, message: 'No view reference' });\n }\n\n const data: Req['AdaptyUIDismissOnboardingView.Request'] = {\n method: methodKey,\n id: this.id,\n destroy: true,\n };\n\n await this.adaptyPlugin.handleMethodCall(methodKey, JSON.stringify(data), ctx, log);\n }\n\n private onRequestClose = async () => {\n try {\n await this.dismiss();\n } catch (error) {\n Log.warn(\n 'setEventHandlers',\n () => 'Failed to dismiss onboarding',\n () => ({ error }),\n );\n }\n };\n\n /**\n * Registers event handlers for onboarding UI events.\n *\n * @remarks\n * Each event type can have only one handler — new handlers replace existing ones.\n * Default handlers are registered automatically in {@link createOnboardingView} and provide standard closing behavior:\n * - `onClose` - closes the onboarding when the close button is pressed or system back is used\n *\n * If you want to override the `onClose` listener, we strongly recommend returning `true`\n * from your custom listener to retain default closing behavior.\n *\n * Calling this method multiple times will replace previously registered handlers for provided events.\n *\n * @see {@link https://adapty.io/docs/capacitor-handling-onboarding-events | Handling Onboarding Events}\n *\n * @param eventHandlers - Set of event handling callbacks. Only provided handlers will be registered or updated.\n * @returns A promise that resolves to an unsubscribe function that removes all registered listeners.\n *\n * @example\n * Register custom event handlers\n * ```typescript\n * import { createOnboardingView } from '@adapty/capacitor';\n *\n * const view = await createOnboardingView(onboarding);\n *\n * const unsubscribe = await view.setEventHandlers({\n * onClose: () => {\n * console.log('Onboarding closed');\n * // Return true to keep default closing behavior\n * return true;\n * },\n * onActionPerformed: (action) => {\n * console.log('Action performed:', action.name);\n * },\n * onProductSelected: (product) => {\n * console.log('Product selected:', product.vendorProductId);\n * }\n * });\n *\n * await view.present();\n *\n * // Later, unsubscribe all handlers\n * unsubscribe();\n * ```\n */\n public async setEventHandlers(eventHandlers: Partial<OnboardingEventHandlers> = {}): Promise<() => void> {\n const ctx = new LogContext();\n const log = ctx.call({ methodName: 'setEventHandlers' });\n log.start(() => ({ _id: this.id }));\n\n if (this.id === null) {\n throw new AdaptyError({ adaptyCode: 2002, message: 'No view reference' });\n }\n\n Log.verbose(\n 'setEventHandlers',\n () => 'Registering onboarding event handlers for view',\n () => ({ id: this.id }),\n );\n\n const viewEmitter = this.viewEmitter ?? new OnboardingViewEmitter(this.id);\n this.viewEmitter = viewEmitter;\n\n const wrappedErrorLogEventHandlers = mapValues(eventHandlers, (handler, eventName) =>\n handler && typeof handler === 'function'\n ? withErrorContext(handler, eventName as string, 'OnboardingViewController')\n : undefined,\n );\n\n // Merge with defaults to ensure default behavior is preserved after unsubscribe/resubscribe cycles\n const finalEventHandlers: Partial<OnboardingEventHandlers> = {\n ...DEFAULT_ONBOARDING_EVENT_HANDLERS,\n ...wrappedErrorLogEventHandlers,\n };\n\n for (const [eventName, handler] of Object.entries(finalEventHandlers)) {\n if (handler && typeof handler === 'function') {\n try {\n await viewEmitter.addListener(eventName as keyof OnboardingEventHandlers, handler, this.onRequestClose);\n Log.verbose(\n 'setEventHandlers',\n () => 'Registered onboarding handler',\n () => ({ eventName }),\n );\n } catch (error) {\n Log.error(\n 'setEventHandlers',\n () => `Failed to register onboarding handler for ${eventName}`,\n () => ({ error }),\n );\n }\n }\n }\n\n const unsubscribe = () => {\n Log.info(\n 'setEventHandlers',\n () => 'Unsubscribing onboarding event handlers for view',\n () => ({ id: this.id }),\n );\n if (this.viewEmitter) {\n this.viewEmitter.removeAllListeners();\n this.viewEmitter = null;\n }\n };\n\n return unsubscribe;\n }\n\n /**\n * Clears all registered event handlers.\n *\n * @remarks\n * This method removes all previously registered event handlers.\n * After calling this method, no event handlers will be active\n * until you call {@link setEventHandlers} again.\n *\n * Use this after dismiss to remove all event handlers.\n *\n * @example\n * ```typescript\n * const view = await createOnboardingView(onboarding);\n * await view.setEventHandlers({ onClose: handleClose });\n *\n * // Later, clear all handlers\n * view.clearEventHandlers();\n * ```\n */\n public clearEventHandlers(): void {\n Log.info(\n 'clearEventHandlers',\n () => 'Clearing all onboarding event handlers for view',\n () => ({ id: this.id }),\n );\n\n if (this.viewEmitter) {\n this.viewEmitter.removeAllListeners();\n this.viewEmitter = null;\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"onboarding-view-controller.js","sourceRoot":"","sources":["../../../src/ui-builder/onboarding-view-controller.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Adapty } from '../adapty';\nimport { AdaptyError } from '../shared/adapty-error';\nimport { AdaptyOnboardingCoder } from '../shared/coders/adapty-onboarding';\nimport { AdaptyUICreateOnboardingViewParamsCoder } from '../shared/coders/adapty-ui-create-onboarding-view-params';\nimport { LogContext, Log } from '../shared/logger';\nimport { WebPresentation } from '../shared/types';\nimport type { AdaptyOnboarding } from '../shared/types';\nimport type { components } from '../shared/types/api';\nimport { mapValues } from '../shared/utils/map-values';\nimport { withErrorContext } from '../shared/utils/with-error-context';\n\nimport { OnboardingViewEmitter } from './onboarding-view-emitter';\nimport { DEFAULT_ONBOARDING_EVENT_HANDLERS } from './types';\nimport type {\n AdaptyUiView,\n OnboardingEventHandlers,\n AdaptyIOSPresentationStyle,\n CreateOnboardingViewParamsInput,\n} from './types';\n\ntype Req = components['requests'];\n\nexport const DEFAULT_ONBOARDING_PARAMS: CreateOnboardingViewParamsInput = {\n externalUrlsPresentation: WebPresentation.BrowserInApp,\n};\n\n/**\n * Controller for managing onboarding views.\n *\n * @remarks\n * This class provides methods to present, dismiss, and handle events for onboarding views\n * created with the Onboarding Builder. Create instances using the {@link createOnboardingView} function\n * rather than directly constructing this class.\n *\n * @public\n */\nexport class OnboardingViewController {\n private id: string | null = null;\n private adaptyPlugin: Adapty;\n private viewEmitter: OnboardingViewEmitter | null = null;\n\n /**\n * Intended way to create a OnboardingViewController instance.\n * It prepares a native controller to be presented\n * and creates reference between native controller and JS instance\n * @internal\n */\n static async create(\n onboarding: AdaptyOnboarding,\n adaptyPlugin: Adapty,\n params: CreateOnboardingViewParamsInput = {},\n ): Promise<OnboardingViewController> {\n const controller = new OnboardingViewController(adaptyPlugin);\n\n const ctx = new LogContext();\n const methodKey = 'adapty_ui_create_onboarding_view';\n const log = ctx.call({ methodName: methodKey });\n log.start(() => ({ onboarding, params }));\n\n const coder = new AdaptyOnboardingCoder();\n const paramsWithDefaults = { ...DEFAULT_ONBOARDING_PARAMS, ...params };\n const encodedParams = new AdaptyUICreateOnboardingViewParamsCoder().encode(paramsWithDefaults);\n\n const data: Req['AdaptyUICreateOnboardingView.Request'] = {\n method: methodKey,\n onboarding: coder.encode(onboarding),\n ...encodedParams,\n };\n\n const result = (await controller.adaptyPlugin.handleMethodCall(\n methodKey,\n JSON.stringify(data),\n ctx,\n log,\n )) as AdaptyUiView;\n controller.id = result.id;\n\n await controller.setEventHandlers(DEFAULT_ONBOARDING_EVENT_HANDLERS);\n\n return controller;\n }\n\n /**\n * Since constructors in JS cannot be async, it is not\n * preferred to create ViewControllers in direct way.\n * Consider using @link{OnboardingViewController.create} instead\n *\n * @internal\n */\n private constructor(adaptyPlugin: Adapty) {\n this.adaptyPlugin = adaptyPlugin;\n }\n\n /**\n * Presents the onboarding view as a modal screen.\n *\n * @remarks\n * Calling `present` on an already visible onboarding view will result in an error.\n * The onboarding will be displayed with the configured presentation style on iOS.\n * On Android, the onboarding is always presented as a full-screen activity.\n *\n * @param options - Optional presentation options\n * @param options.iosPresentationStyle - iOS presentation style. Available options: `'full_screen'` (default) or `'page_sheet'`. Only affects iOS platform.\n * @returns A promise that resolves when the onboarding is presented.\n * @throws {@link AdaptyError} if the view reference is invalid or the view is already presented.\n *\n * @example\n * Present with default full-screen style\n * ```typescript\n * import { adapty, createOnboardingView } from '@adapty/capacitor';\n *\n * const onboarding = await adapty.getOnboarding({ placementId: 'YOUR_PLACEMENT_ID' });\n * const view = await createOnboardingView(onboarding);\n * await view.present();\n * ```\n *\n * @example\n * Present with page sheet style on iOS\n * ```typescript\n * await view.present({ iosPresentationStyle: 'page_sheet' });\n * ```\n */\n public async present(options: { iosPresentationStyle?: AdaptyIOSPresentationStyle } = {}): Promise<void> {\n const ctx = new LogContext();\n const methodKey = 'adapty_ui_present_onboarding_view';\n const log = ctx.call({ methodName: methodKey });\n log.start(() => ({ _id: this.id, iosPresentationStyle: options.iosPresentationStyle }));\n\n if (this.id === null) {\n throw new AdaptyError({ adaptyCode: 2002, message: 'No view reference' });\n }\n\n const data: any = {\n method: methodKey,\n id: this.id,\n ios_presentation_style: options.iosPresentationStyle ?? 'full_screen',\n };\n\n await this.adaptyPlugin.handleMethodCall(methodKey, JSON.stringify(data), ctx, log);\n }\n\n /**\n * Dismisses the onboarding view.\n *\n * @remarks\n * This method closes the onboarding and cleans up associated resources.\n * After dismissing, the view controller instance cannot be reused.\n *\n * @returns A promise that resolves when the onboarding is dismissed.\n * @throws {@link AdaptyError} if the view reference is invalid.\n *\n * @example\n * ```typescript\n * import { createOnboardingView } from '@adapty/capacitor';\n *\n * const view = await createOnboardingView(onboarding);\n * await view.present();\n * // ... later\n * await view.dismiss();\n * ```\n */\n public async dismiss(): Promise<void> {\n const ctx = new LogContext();\n const methodKey = 'adapty_ui_dismiss_onboarding_view';\n const log = ctx.call({ methodName: methodKey });\n log.start(() => ({ _id: this.id }));\n\n if (this.id === null) {\n throw new AdaptyError({ adaptyCode: 2002, message: 'No view reference' });\n }\n\n const data: Req['AdaptyUIDismissOnboardingView.Request'] = {\n method: methodKey,\n id: this.id,\n destroy: true,\n };\n\n await this.adaptyPlugin.handleMethodCall(methodKey, JSON.stringify(data), ctx, log);\n this.clearEventHandlers();\n }\n\n private onRequestClose = async () => {\n try {\n await this.dismiss();\n } catch (error) {\n Log.warn(\n 'setEventHandlers',\n () => 'Failed to dismiss onboarding',\n () => ({ error }),\n );\n }\n };\n\n /**\n * Registers event handlers for onboarding UI events.\n *\n * @remarks\n * Each event type can have only one handler — new handlers replace existing ones.\n * Default handlers are registered automatically in {@link createOnboardingView} and provide standard closing behavior:\n * - `onClose` - closes the onboarding when the close button is pressed or system back is used\n *\n * If you want to override the `onClose` listener, we strongly recommend returning `true`\n * from your custom listener to retain default closing behavior.\n *\n * Calling this method multiple times will replace previously registered handlers for provided events.\n *\n * @see {@link https://adapty.io/docs/capacitor-handling-onboarding-events | Handling Onboarding Events}\n *\n * @param eventHandlers - Set of event handling callbacks. Only provided handlers will be registered or updated.\n * @returns A promise that resolves to an unsubscribe function that removes all registered listeners.\n *\n * @example\n * Register custom event handlers\n * ```typescript\n * import { createOnboardingView } from '@adapty/capacitor';\n *\n * const view = await createOnboardingView(onboarding);\n *\n * const unsubscribe = await view.setEventHandlers({\n * onClose: () => {\n * console.log('Onboarding closed');\n * // Return true to keep default closing behavior\n * return true;\n * },\n * onActionPerformed: (action) => {\n * console.log('Action performed:', action.name);\n * },\n * onProductSelected: (product) => {\n * console.log('Product selected:', product.vendorProductId);\n * }\n * });\n *\n * await view.present();\n *\n * // Later, unsubscribe all handlers\n * unsubscribe();\n * ```\n */\n public async setEventHandlers(eventHandlers: Partial<OnboardingEventHandlers> = {}): Promise<() => void> {\n const ctx = new LogContext();\n const log = ctx.call({ methodName: 'setEventHandlers' });\n log.start(() => ({ _id: this.id }));\n\n if (this.id === null) {\n throw new AdaptyError({ adaptyCode: 2002, message: 'No view reference' });\n }\n\n Log.verbose(\n 'setEventHandlers',\n () => 'Registering onboarding event handlers for view',\n () => ({ id: this.id }),\n );\n\n const viewEmitter = this.viewEmitter ?? new OnboardingViewEmitter(this.id);\n this.viewEmitter = viewEmitter;\n\n const wrappedErrorLogEventHandlers = mapValues(eventHandlers, (handler, eventName) =>\n handler && typeof handler === 'function'\n ? withErrorContext(handler, eventName as string, 'OnboardingViewController')\n : undefined,\n );\n\n // Merge with defaults to ensure default behavior is preserved after unsubscribe/resubscribe cycles\n const finalEventHandlers: Partial<OnboardingEventHandlers> = {\n ...DEFAULT_ONBOARDING_EVENT_HANDLERS,\n ...wrappedErrorLogEventHandlers,\n };\n\n for (const [eventName, handler] of Object.entries(finalEventHandlers)) {\n if (handler && typeof handler === 'function') {\n try {\n await viewEmitter.addListener(eventName as keyof OnboardingEventHandlers, handler, this.onRequestClose);\n Log.verbose(\n 'setEventHandlers',\n () => 'Registered onboarding handler',\n () => ({ eventName }),\n );\n } catch (error) {\n Log.error(\n 'setEventHandlers',\n () => `Failed to register onboarding handler for ${eventName}`,\n () => ({ error }),\n );\n }\n }\n }\n\n const unsubscribe = () => {\n Log.info(\n 'setEventHandlers',\n () => 'Unsubscribing onboarding event handlers for view',\n () => ({ id: this.id }),\n );\n if (this.viewEmitter) {\n this.viewEmitter.removeAllListeners();\n this.viewEmitter = null;\n }\n };\n\n return unsubscribe;\n }\n\n /**\n * Clears all registered event handlers.\n *\n * @remarks\n * This method removes all previously registered event handlers.\n * After calling this method, no event handlers will be active\n * until you call {@link setEventHandlers} again.\n *\n * Use this after dismiss to remove all event handlers.\n *\n * @example\n * ```typescript\n * const view = await createOnboardingView(onboarding);\n * await view.setEventHandlers({ onClose: handleClose });\n *\n * // Later, clear all handlers\n * view.clearEventHandlers();\n * ```\n */\n public clearEventHandlers(): void {\n Log.info(\n 'clearEventHandlers',\n () => 'Clearing all onboarding event handlers for view',\n () => ({ id: this.id }),\n );\n\n if (this.viewEmitter) {\n this.viewEmitter.removeAllListeners();\n this.viewEmitter = null;\n }\n }\n}\n"]}
|
|
@@ -1,32 +1,18 @@
|
|
|
1
1
|
import type { LogContext } from '../shared/logger';
|
|
2
|
-
import type {
|
|
3
|
-
import { BaseViewEmitter
|
|
4
|
-
import type {
|
|
5
|
-
|
|
6
|
-
id?: string;
|
|
7
|
-
meta?: AdaptyUiOnboardingMeta;
|
|
8
|
-
event?: {
|
|
9
|
-
name: string;
|
|
10
|
-
element_id?: string;
|
|
11
|
-
reply?: string;
|
|
12
|
-
};
|
|
13
|
-
action?: OnboardingStateUpdatedAction;
|
|
14
|
-
error?: AdaptyError;
|
|
15
|
-
view?: {
|
|
16
|
-
id: string;
|
|
17
|
-
};
|
|
18
|
-
}
|
|
2
|
+
import type { OnboardingEventIdType, ParsedOnboardingEvent } from '../shared/types/onboarding-events';
|
|
3
|
+
import { BaseViewEmitter } from './base-view-emitter';
|
|
4
|
+
import type { OnboardingEventHandlers } from './types';
|
|
5
|
+
type OnboardingNativeEvent = OnboardingEventIdType;
|
|
19
6
|
/**
|
|
20
7
|
* OnboardingViewEmitter manages event handlers for onboarding view events.
|
|
21
8
|
* Each event type can have only one handler - new handlers replace existing ones.
|
|
22
9
|
*/
|
|
23
|
-
export declare class OnboardingViewEmitter extends BaseViewEmitter<OnboardingEventHandlers,
|
|
24
|
-
protected
|
|
25
|
-
protected
|
|
26
|
-
protected
|
|
27
|
-
protected extractCallbackArgs(handlerName: keyof OnboardingEventHandlers, eventData:
|
|
28
|
-
protected getEventViewId(eventData:
|
|
29
|
-
protected shouldCallHandler(): boolean;
|
|
10
|
+
export declare class OnboardingViewEmitter extends BaseViewEmitter<OnboardingEventHandlers, ParsedOnboardingEvent, OnboardingNativeEvent> {
|
|
11
|
+
protected parseEventData(rawEventData: string, ctx: LogContext): ParsedOnboardingEvent;
|
|
12
|
+
protected getNativeEventForHandler(event: keyof OnboardingEventHandlers): OnboardingNativeEvent | null;
|
|
13
|
+
protected getHandlerForNativeEvent(nativeEvent: OnboardingNativeEvent): keyof OnboardingEventHandlers | null;
|
|
14
|
+
protected extractCallbackArgs(handlerName: keyof OnboardingEventHandlers, eventData: ParsedOnboardingEvent): unknown[];
|
|
15
|
+
protected getEventViewId(eventData: ParsedOnboardingEvent): string | null;
|
|
30
16
|
protected getEmitterName(): string;
|
|
31
17
|
}
|
|
32
18
|
export {};
|
|
@@ -1,18 +1,24 @@
|
|
|
1
|
-
import { parseOnboardingEvent } from '../shared/coders/parse';
|
|
1
|
+
import { parseOnboardingEvent } from '../shared/coders/parse-onboarding';
|
|
2
|
+
import { OnboardingEventId } from '../shared/types/onboarding-events';
|
|
2
3
|
import { BaseViewEmitter } from './base-view-emitter';
|
|
3
4
|
/**
|
|
4
5
|
* OnboardingViewEmitter manages event handlers for onboarding view events.
|
|
5
6
|
* Each event type can have only one handler - new handlers replace existing ones.
|
|
6
7
|
*/
|
|
7
8
|
export class OnboardingViewEmitter extends BaseViewEmitter {
|
|
8
|
-
getEventConfig(event) {
|
|
9
|
-
return HANDLER_TO_EVENT_CONFIG[event];
|
|
10
|
-
}
|
|
11
9
|
parseEventData(rawEventData, ctx) {
|
|
12
|
-
|
|
10
|
+
const result = parseOnboardingEvent(rawEventData, ctx);
|
|
11
|
+
if (!result) {
|
|
12
|
+
throw new Error('Failed to parse onboarding event');
|
|
13
|
+
}
|
|
14
|
+
return result;
|
|
15
|
+
}
|
|
16
|
+
getNativeEventForHandler(event) {
|
|
17
|
+
return HANDLER_TO_NATIVE_EVENT[event];
|
|
13
18
|
}
|
|
14
|
-
|
|
15
|
-
|
|
19
|
+
getHandlerForNativeEvent(nativeEvent) {
|
|
20
|
+
var _a;
|
|
21
|
+
return (_a = NATIVE_EVENT_RESOLVER[nativeEvent]) !== null && _a !== void 0 ? _a : null;
|
|
16
22
|
}
|
|
17
23
|
extractCallbackArgs(handlerName, eventData) {
|
|
18
24
|
return extractCallbackArgs(handlerName, eventData);
|
|
@@ -21,60 +27,47 @@ export class OnboardingViewEmitter extends BaseViewEmitter {
|
|
|
21
27
|
var _a, _b;
|
|
22
28
|
return (_b = (_a = eventData === null || eventData === void 0 ? void 0 : eventData.view) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : null;
|
|
23
29
|
}
|
|
24
|
-
shouldCallHandler() {
|
|
25
|
-
// Onboarding events don't use propertyMap filtering
|
|
26
|
-
return true;
|
|
27
|
-
}
|
|
28
30
|
getEmitterName() {
|
|
29
31
|
return 'OnboardingViewEmitter';
|
|
30
32
|
}
|
|
31
33
|
}
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
34
|
+
const HANDLER_TO_NATIVE_EVENT = {
|
|
35
|
+
onError: 'onboarding_did_fail_with_error',
|
|
36
|
+
onAnalytics: 'onboarding_on_analytics_action',
|
|
37
|
+
onFinishedLoading: 'onboarding_did_finish_loading',
|
|
38
|
+
onClose: 'onboarding_on_close_action',
|
|
39
|
+
onCustom: 'onboarding_on_custom_action',
|
|
40
|
+
onPaywall: 'onboarding_on_paywall_action',
|
|
41
|
+
onStateUpdated: 'onboarding_on_state_updated_action',
|
|
40
42
|
};
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
return [action, meta];
|
|
70
|
-
case 'onFinishedLoading':
|
|
71
|
-
return [meta];
|
|
72
|
-
case 'onAnalytics':
|
|
73
|
-
return [event, meta];
|
|
74
|
-
case 'onError':
|
|
75
|
-
return [eventArg.error];
|
|
76
|
-
default:
|
|
77
|
-
return [];
|
|
43
|
+
const NATIVE_EVENT_RESOLVER = {
|
|
44
|
+
onboarding_did_fail_with_error: 'onError',
|
|
45
|
+
onboarding_on_analytics_action: 'onAnalytics',
|
|
46
|
+
onboarding_did_finish_loading: 'onFinishedLoading',
|
|
47
|
+
onboarding_on_close_action: 'onClose',
|
|
48
|
+
onboarding_on_custom_action: 'onCustom',
|
|
49
|
+
onboarding_on_paywall_action: 'onPaywall',
|
|
50
|
+
onboarding_on_state_updated_action: 'onStateUpdated',
|
|
51
|
+
};
|
|
52
|
+
function extractCallbackArgs(_handlerName, event) {
|
|
53
|
+
switch (event.id) {
|
|
54
|
+
case OnboardingEventId.Close:
|
|
55
|
+
case OnboardingEventId.Custom:
|
|
56
|
+
case OnboardingEventId.Paywall:
|
|
57
|
+
return [event.actionId, event.meta];
|
|
58
|
+
case OnboardingEventId.StateUpdated:
|
|
59
|
+
return [event.action, event.meta];
|
|
60
|
+
case OnboardingEventId.FinishedLoading:
|
|
61
|
+
return [event.meta];
|
|
62
|
+
case OnboardingEventId.Analytics:
|
|
63
|
+
return [
|
|
64
|
+
Object.assign(Object.assign({}, event.event), {
|
|
65
|
+
// Add backward compatibility: populate element_id from elementId
|
|
66
|
+
element_id: event.event.elementId }),
|
|
67
|
+
event.meta,
|
|
68
|
+
];
|
|
69
|
+
case OnboardingEventId.Error:
|
|
70
|
+
return [event.error];
|
|
78
71
|
}
|
|
79
72
|
}
|
|
80
73
|
//# sourceMappingURL=onboarding-view-emitter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"onboarding-view-emitter.js","sourceRoot":"","sources":["../../../src/ui-builder/onboarding-view-emitter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"onboarding-view-emitter.js","sourceRoot":"","sources":["../../../src/ui-builder/onboarding-view-emitter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAEzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAGtE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAMtD;;;GAGG;AACH,MAAM,OAAO,qBAAsB,SAAQ,eAI1C;IACW,cAAc,CAAC,YAAoB,EAAE,GAAe;QAC5D,MAAM,MAAM,GAAG,oBAAoB,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QACvD,IAAI,CAAC,MAAM,EAAE;YACX,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;SACrD;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAES,wBAAwB,CAAC,KAAoC;QACrE,OAAO,uBAAuB,CAAC,KAAkB,CAAC,CAAC;IACrD,CAAC;IAES,wBAAwB,CAAC,WAAkC;;QACnE,OAAO,MAAA,qBAAqB,CAAC,WAAW,CAAC,mCAAI,IAAI,CAAC;IACpD,CAAC;IAES,mBAAmB,CAC3B,WAA0C,EAC1C,SAAgC;QAEhC,OAAO,mBAAmB,CAAC,WAAwB,EAAE,SAAS,CAAC,CAAC;IAClE,CAAC;IAES,cAAc,CAAC,SAAgC;;QACvD,OAAO,MAAA,MAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,IAAI,0CAAE,EAAE,mCAAI,IAAI,CAAC;IACrC,CAAC;IAES,cAAc;QACtB,OAAO,uBAAuB,CAAC;IACjC,CAAC;CACF;AAED,MAAM,uBAAuB,GAA6C;IACxE,OAAO,EAAE,gCAAgC;IACzC,WAAW,EAAE,gCAAgC;IAC7C,iBAAiB,EAAE,+BAA+B;IAClD,OAAO,EAAE,4BAA4B;IACrC,QAAQ,EAAE,6BAA6B;IACvC,SAAS,EAAE,8BAA8B;IACzC,cAAc,EAAE,oCAAoC;CACrD,CAAC;AAEF,MAAM,qBAAqB,GAA6C;IACtE,8BAA8B,EAAE,SAAS;IACzC,8BAA8B,EAAE,aAAa;IAC7C,6BAA6B,EAAE,mBAAmB;IAClD,0BAA0B,EAAE,SAAS;IACrC,2BAA2B,EAAE,UAAU;IACvC,4BAA4B,EAAE,WAAW;IACzC,kCAAkC,EAAE,gBAAgB;CACrD,CAAC;AAIF,SAAS,mBAAmB,CAC1B,YAAe,EACf,KAA4B;IAE5B,QAAQ,KAAK,CAAC,EAAE,EAAE;QAChB,KAAK,iBAAiB,CAAC,KAAK,CAAC;QAC7B,KAAK,iBAAiB,CAAC,MAAM,CAAC;QAC9B,KAAK,iBAAiB,CAAC,OAAO;YAC5B,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAqB,CAAC;QAE1D,KAAK,iBAAiB,CAAC,YAAY;YACjC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAqB,CAAC;QAExD,KAAK,iBAAiB,CAAC,eAAe;YACpC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAqB,CAAC;QAE1C,KAAK,iBAAiB,CAAC,SAAS;YAC9B,OAAO;gDAEA,KAAK,CAAC,KAAK;oBACd,iEAAiE;oBACjE,UAAU,EAAE,KAAK,CAAC,KAAK,CAAC,SAAS;gBAEnC,KAAK,CAAC,IAAI;aACS,CAAC;QAExB,KAAK,iBAAiB,CAAC,KAAK;YAC1B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAqB,CAAC;KAC5C;AACH,CAAC","sourcesContent":["import { parseOnboardingEvent } from '../shared/coders/parse-onboarding';\nimport type { LogContext } from '../shared/logger';\nimport { OnboardingEventId } from '../shared/types/onboarding-events';\nimport type { OnboardingEventIdType, ParsedOnboardingEvent } from '../shared/types/onboarding-events';\n\nimport { BaseViewEmitter } from './base-view-emitter';\nimport type { OnboardingEventHandlers } from './types';\n\ntype EventName = keyof OnboardingEventHandlers;\ntype OnboardingNativeEvent = OnboardingEventIdType;\n\n/**\n * OnboardingViewEmitter manages event handlers for onboarding view events.\n * Each event type can have only one handler - new handlers replace existing ones.\n */\nexport class OnboardingViewEmitter extends BaseViewEmitter<\n OnboardingEventHandlers,\n ParsedOnboardingEvent,\n OnboardingNativeEvent\n> {\n protected parseEventData(rawEventData: string, ctx: LogContext): ParsedOnboardingEvent {\n const result = parseOnboardingEvent(rawEventData, ctx);\n if (!result) {\n throw new Error('Failed to parse onboarding event');\n }\n return result;\n }\n\n protected getNativeEventForHandler(event: keyof OnboardingEventHandlers): OnboardingNativeEvent | null {\n return HANDLER_TO_NATIVE_EVENT[event as EventName];\n }\n\n protected getHandlerForNativeEvent(nativeEvent: OnboardingNativeEvent): keyof OnboardingEventHandlers | null {\n return NATIVE_EVENT_RESOLVER[nativeEvent] ?? null;\n }\n\n protected extractCallbackArgs(\n handlerName: keyof OnboardingEventHandlers,\n eventData: ParsedOnboardingEvent,\n ): unknown[] {\n return extractCallbackArgs(handlerName as EventName, eventData);\n }\n\n protected getEventViewId(eventData: ParsedOnboardingEvent): string | null {\n return eventData?.view?.id ?? null;\n }\n\n protected getEmitterName(): string {\n return 'OnboardingViewEmitter';\n }\n}\n\nconst HANDLER_TO_NATIVE_EVENT: Record<EventName, OnboardingNativeEvent> = {\n onError: 'onboarding_did_fail_with_error',\n onAnalytics: 'onboarding_on_analytics_action',\n onFinishedLoading: 'onboarding_did_finish_loading',\n onClose: 'onboarding_on_close_action',\n onCustom: 'onboarding_on_custom_action',\n onPaywall: 'onboarding_on_paywall_action',\n onStateUpdated: 'onboarding_on_state_updated_action',\n};\n\nconst NATIVE_EVENT_RESOLVER: Record<OnboardingNativeEvent, EventName> = {\n onboarding_did_fail_with_error: 'onError',\n onboarding_on_analytics_action: 'onAnalytics',\n onboarding_did_finish_loading: 'onFinishedLoading',\n onboarding_on_close_action: 'onClose',\n onboarding_on_custom_action: 'onCustom',\n onboarding_on_paywall_action: 'onPaywall',\n onboarding_on_state_updated_action: 'onStateUpdated',\n};\n\ntype ExtractedArgs<T extends keyof OnboardingEventHandlers> = Parameters<OnboardingEventHandlers[T]>;\n\nfunction extractCallbackArgs<T extends keyof OnboardingEventHandlers>(\n _handlerName: T,\n event: ParsedOnboardingEvent,\n): ExtractedArgs<T> {\n switch (event.id) {\n case OnboardingEventId.Close:\n case OnboardingEventId.Custom:\n case OnboardingEventId.Paywall:\n return [event.actionId, event.meta] as ExtractedArgs<T>;\n\n case OnboardingEventId.StateUpdated:\n return [event.action, event.meta] as ExtractedArgs<T>;\n\n case OnboardingEventId.FinishedLoading:\n return [event.meta] as ExtractedArgs<T>;\n\n case OnboardingEventId.Analytics:\n return [\n {\n ...event.event,\n // Add backward compatibility: populate element_id from elementId\n element_id: event.event.elementId,\n },\n event.meta,\n ] as ExtractedArgs<T>;\n\n case OnboardingEventId.Error:\n return [event.error] as ExtractedArgs<T>;\n }\n}\n"]}
|
|
@@ -125,6 +125,7 @@ export declare class PaywallViewController {
|
|
|
125
125
|
* - `onCloseButtonPress` - closes the paywall
|
|
126
126
|
* - `onAndroidSystemBack` - closes the paywall (Android only)
|
|
127
127
|
* - `onRestoreCompleted` - closes the paywall after successful restore
|
|
128
|
+
* - `onRenderingFailed` - closes the paywall when rendering fails
|
|
128
129
|
* - `onPurchaseCompleted` - closes the paywall after successful purchase
|
|
129
130
|
*
|
|
130
131
|
* If you want to override these listeners, we strongly recommend returning `true`
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { AdaptyError } from '../shared/adapty-error';
|
|
2
2
|
import { AdaptyPaywallCoder } from '../shared/coders/adapty-paywall';
|
|
3
|
+
import { AdaptyUICreatePaywallViewParamsCoder } from '../shared/coders/adapty-ui-create-paywall-view-params';
|
|
3
4
|
import { LogContext, Log } from '../shared/logger';
|
|
4
5
|
import { mapValues } from '../shared/utils/map-values';
|
|
5
6
|
import { withErrorContext } from '../shared/utils/with-error-context';
|
|
6
7
|
import { PaywallViewEmitter } from './paywall-view-emitter';
|
|
7
8
|
import { DEFAULT_EVENT_HANDLERS } from './types';
|
|
9
|
+
const DEFAULT_PARAMS = {
|
|
10
|
+
prefetchProducts: true,
|
|
11
|
+
loadTimeoutMs: 5000,
|
|
12
|
+
};
|
|
8
13
|
/**
|
|
9
14
|
* Controller for managing paywall views.
|
|
10
15
|
*
|
|
@@ -23,54 +28,18 @@ export class PaywallViewController {
|
|
|
23
28
|
* @internal
|
|
24
29
|
*/
|
|
25
30
|
static async create(paywall, params, adaptyPlugin) {
|
|
26
|
-
var _a, _b;
|
|
27
31
|
const controller = new PaywallViewController(adaptyPlugin);
|
|
28
32
|
const ctx = new LogContext();
|
|
29
33
|
const methodKey = 'adapty_ui_create_paywall_view';
|
|
30
34
|
const log = ctx.call({ methodName: methodKey });
|
|
31
35
|
log.start(() => ({ paywall, params }));
|
|
32
|
-
const
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
preload_products: (_a = params.prefetchProducts) !== null && _a !== void 0 ? _a : true,
|
|
37
|
-
load_timeout: ((_b = params.loadTimeoutMs) !== null && _b !== void 0 ? _b : 5000) / 1000,
|
|
38
|
-
};
|
|
39
|
-
if (params.customTags) {
|
|
40
|
-
data.custom_tags = params.customTags;
|
|
41
|
-
}
|
|
42
|
-
if (params.customTimers) {
|
|
43
|
-
const convertTimerInfo = (timerInfo) => {
|
|
44
|
-
const formatDate = (date) => {
|
|
45
|
-
const pad = (num, digits = 2) => {
|
|
46
|
-
const str = num.toString();
|
|
47
|
-
const paddingLength = digits - str.length;
|
|
48
|
-
return paddingLength > 0 ? '0'.repeat(paddingLength) + str : str;
|
|
49
|
-
};
|
|
50
|
-
const year = date.getUTCFullYear();
|
|
51
|
-
const month = pad(date.getUTCMonth() + 1);
|
|
52
|
-
const day = pad(date.getUTCDate());
|
|
53
|
-
const hours = pad(date.getUTCHours());
|
|
54
|
-
const minutes = pad(date.getUTCMinutes());
|
|
55
|
-
const seconds = pad(date.getUTCSeconds());
|
|
56
|
-
const millis = pad(date.getUTCMilliseconds(), 3);
|
|
57
|
-
return `${year}-${month}-${day}T${hours}:${minutes}:${seconds}.${millis}Z`;
|
|
58
|
-
};
|
|
59
|
-
const result = {};
|
|
60
|
-
for (const key in timerInfo) {
|
|
61
|
-
if (Object.prototype.hasOwnProperty.call(timerInfo, key)) {
|
|
62
|
-
const date = timerInfo[key];
|
|
63
|
-
if (date instanceof Date) {
|
|
64
|
-
result[key] = formatDate(date);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
return result;
|
|
69
|
-
};
|
|
70
|
-
data.custom_timers = convertTimerInfo(params.customTimers);
|
|
71
|
-
}
|
|
36
|
+
const paywallCoder = new AdaptyPaywallCoder();
|
|
37
|
+
const paramsCoder = new AdaptyUICreatePaywallViewParamsCoder();
|
|
38
|
+
const paramsWithDefaults = Object.assign(Object.assign({}, DEFAULT_PARAMS), params);
|
|
39
|
+
const data = Object.assign({ method: methodKey, paywall: paywallCoder.encode(paywall) }, paramsCoder.encode(paramsWithDefaults));
|
|
72
40
|
const result = (await controller.adaptyPlugin.handleMethodCall(methodKey, JSON.stringify(data), ctx, log));
|
|
73
41
|
controller.id = result.id;
|
|
42
|
+
controller.viewEmitter = new PaywallViewEmitter(controller.id);
|
|
74
43
|
await controller.setEventHandlers(DEFAULT_EVENT_HANDLERS);
|
|
75
44
|
return controller;
|
|
76
45
|
}
|
|
@@ -179,6 +148,7 @@ export class PaywallViewController {
|
|
|
179
148
|
destroy: true,
|
|
180
149
|
};
|
|
181
150
|
await this.adaptyPlugin.handleMethodCall(methodKey, JSON.stringify(data), ctx, log);
|
|
151
|
+
this.clearEventHandlers();
|
|
182
152
|
}
|
|
183
153
|
/**
|
|
184
154
|
* Displays a dialog to the user.
|
|
@@ -244,6 +214,7 @@ export class PaywallViewController {
|
|
|
244
214
|
* - `onCloseButtonPress` - closes the paywall
|
|
245
215
|
* - `onAndroidSystemBack` - closes the paywall (Android only)
|
|
246
216
|
* - `onRestoreCompleted` - closes the paywall after successful restore
|
|
217
|
+
* - `onRenderingFailed` - closes the paywall when rendering fails
|
|
247
218
|
* - `onPurchaseCompleted` - closes the paywall after successful purchase
|
|
248
219
|
*
|
|
249
220
|
* If you want to override these listeners, we strongly recommend returning `true`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paywall-view-controller.js","sourceRoot":"","sources":["../../../src/ui-builder/paywall-view-controller.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Adapty } from '../adapty';\nimport { AdaptyError } from '../shared/adapty-error';\nimport { AdaptyPaywallCoder } from '../shared/coders/adapty-paywall';\nimport { LogContext, Log } from '../shared/logger';\nimport type { AdaptyPaywall } from '../shared/types';\nimport type { components } from '../shared/types/api';\nimport { mapValues } from '../shared/utils/map-values';\nimport { withErrorContext } from '../shared/utils/with-error-context';\n\nimport { PaywallViewEmitter } from './paywall-view-emitter';\nimport type {\n AdaptyUiView,\n CreatePaywallViewParamsInput,\n AdaptyUiDialogConfig,\n AdaptyUiDialogActionType,\n EventHandlers,\n AdaptyIOSPresentationStyle,\n} from './types';\nimport { DEFAULT_EVENT_HANDLERS } from './types';\n\ntype Req = components['requests'];\n\n/**\n * Controller for managing paywall views.\n *\n * @remarks\n * This class provides methods to present, dismiss, and handle events for paywall views\n * created with the Paywall Builder. Create instances using the {@link createPaywallView} function\n * rather than directly constructing this class.\n *\n * @public\n */\nexport class PaywallViewController {\n private id: string | null = null;\n private adaptyPlugin: Adapty;\n private viewEmitter: PaywallViewEmitter | null = null;\n\n /**\n * Intended way to create a ViewController instance.\n * It prepares a native controller to be presented\n * and creates reference between native controller and JS instance\n * @internal\n */\n static async create(\n paywall: AdaptyPaywall,\n params: CreatePaywallViewParamsInput,\n adaptyPlugin: Adapty,\n ): Promise<PaywallViewController> {\n const controller = new PaywallViewController(adaptyPlugin);\n\n const ctx = new LogContext();\n const methodKey = 'adapty_ui_create_paywall_view';\n const log = ctx.call({ methodName: methodKey });\n log.start(() => ({ paywall, params }));\n\n const coder = new AdaptyPaywallCoder();\n const data: Req['AdaptyUICreatePaywallView.Request'] = {\n method: methodKey,\n paywall: coder.encode(paywall),\n preload_products: params.prefetchProducts ?? true,\n load_timeout: (params.loadTimeoutMs ?? 5000) / 1000,\n };\n\n if (params.customTags) {\n data.custom_tags = params.customTags;\n }\n\n if (params.customTimers) {\n const convertTimerInfo = (timerInfo: Record<string, Date>): Record<string, string> => {\n const formatDate = (date: Date): string => {\n const pad = (num: number, digits = 2): string => {\n const str = num.toString();\n const paddingLength = digits - str.length;\n return paddingLength > 0 ? '0'.repeat(paddingLength) + str : str;\n };\n\n const year = date.getUTCFullYear();\n const month = pad(date.getUTCMonth() + 1);\n const day = pad(date.getUTCDate());\n const hours = pad(date.getUTCHours());\n const minutes = pad(date.getUTCMinutes());\n const seconds = pad(date.getUTCSeconds());\n const millis = pad(date.getUTCMilliseconds(), 3);\n\n return `${year}-${month}-${day}T${hours}:${minutes}:${seconds}.${millis}Z`;\n };\n\n const result: Record<string, string> = {};\n for (const key in timerInfo) {\n if (Object.prototype.hasOwnProperty.call(timerInfo, key)) {\n const date = timerInfo[key];\n if (date instanceof Date) {\n result[key] = formatDate(date);\n }\n }\n }\n return result;\n };\n data.custom_timers = convertTimerInfo(params.customTimers);\n }\n\n const result = (await controller.adaptyPlugin.handleMethodCall(\n methodKey,\n JSON.stringify(data),\n ctx,\n log,\n )) as AdaptyUiView;\n controller.id = result.id;\n\n await controller.setEventHandlers(DEFAULT_EVENT_HANDLERS);\n\n return controller;\n }\n\n /**\n * Since constructors in JS cannot be async, it is not\n * preferred to create ViewControllers in direct way.\n * Consider using @link{ViewController.create} instead\n *\n * @internal\n */\n private constructor(adaptyPlugin: Adapty) {\n this.adaptyPlugin = adaptyPlugin;\n }\n\n /**\n * Presents the paywall view as a modal screen.\n *\n * @remarks\n * Calling `present` on an already visible paywall view will result in an error.\n * The paywall will be displayed with the configured presentation style on iOS.\n * On Android, the paywall is always presented as a full-screen activity.\n *\n * @param options - Optional presentation options\n * @param options.iosPresentationStyle - iOS presentation style. Available options: `'full_screen'` (default) or `'page_sheet'`. Only affects iOS platform.\n * @returns A promise that resolves when the paywall is presented.\n * @throws {@link AdaptyError} if the view reference is invalid or the view is already presented.\n *\n * @example\n * Present with default full-screen style\n * ```typescript\n * import { adapty, createPaywallView } from '@adapty/capacitor';\n *\n * const paywall = await adapty.getPaywall({ placementId: 'YOUR_PLACEMENT_ID' });\n * const view = await createPaywallView(paywall);\n * await view.present();\n * ```\n *\n * @example\n * Present with page sheet style on iOS\n * ```typescript\n * await view.present({ iosPresentationStyle: 'page_sheet' });\n * ```\n */\n public async present(options: { iosPresentationStyle?: AdaptyIOSPresentationStyle } = {}): Promise<void> {\n const ctx = new LogContext();\n const methodKey = 'adapty_ui_present_paywall_view';\n const log = ctx.call({ methodName: methodKey });\n log.start(() => ({ _id: this.id, iosPresentationStyle: options.iosPresentationStyle }));\n\n if (this.id === null) {\n throw new AdaptyError({\n adaptyCode: 2002,\n message: 'No view reference',\n });\n }\n\n const data: any = {\n method: methodKey,\n id: this.id,\n ios_presentation_style: options.iosPresentationStyle ?? 'full_screen',\n };\n\n await this.adaptyPlugin.handleMethodCall(methodKey, JSON.stringify(data), ctx, log);\n }\n\n /**\n * Dismisses the paywall view.\n *\n * @remarks\n * This method closes the paywall and cleans up associated resources.\n * After dismissing, the view controller instance cannot be reused.\n *\n * @returns A promise that resolves when the paywall is dismissed.\n * @throws {@link AdaptyError} if the view reference is invalid.\n *\n * @example\n * ```typescript\n * import { createPaywallView } from '@adapty/capacitor';\n *\n * const view = await createPaywallView(paywall);\n * await view.present();\n * // ... later\n * await view.dismiss();\n * ```\n */\n public async dismiss(): Promise<void> {\n const ctx = new LogContext();\n const methodKey = 'adapty_ui_dismiss_paywall_view';\n const log = ctx.call({ methodName: methodKey });\n log.start(() => ({ _id: this.id }));\n\n if (this.id === null) {\n throw new AdaptyError({\n adaptyCode: 2002,\n message: 'No view reference',\n });\n }\n\n const data: Req['AdaptyUIDismissPaywallView.Request'] = {\n method: methodKey,\n id: this.id,\n destroy: true,\n };\n\n await this.adaptyPlugin.handleMethodCall(methodKey, JSON.stringify(data), ctx, log);\n }\n\n /**\n * Displays a dialog to the user.\n *\n * @remarks\n * Use this method to show custom dialogs within the paywall flow.\n * If you provide two actions in the config, the primary action should cancel the operation\n * and leave things unchanged, while the secondary action should confirm the operation.\n *\n * @param config - Configuration for the dialog.\n * @param config.title - The dialog title.\n * @param config.content - The dialog message content.\n * @param config.primaryActionTitle - The title for the primary (default) action button.\n * @param config.secondaryActionTitle - Optional. The title for the secondary action button.\n * @returns A promise that resolves to the action type that the user selected: `'primary'` or `'secondary'`.\n * @throws {@link AdaptyError} if the view reference is invalid.\n *\n * @example\n * Show confirmation dialog\n * ```typescript\n * const action = await view.showDialog({\n * title: 'Confirm Purchase',\n * content: 'Are you sure you want to proceed with this purchase?',\n * primaryActionTitle: 'Cancel',\n * secondaryActionTitle: 'Continue'\n * });\n *\n * if (action === 'secondary') {\n * console.log('User confirmed');\n * }\n * ```\n */\n public async showDialog(config: AdaptyUiDialogConfig): Promise<AdaptyUiDialogActionType> {\n const ctx = new LogContext();\n const methodKey = 'adapty_ui_show_dialog';\n const log = ctx.call({ methodName: methodKey });\n log.start(() => ({ _id: this.id }));\n\n if (this.id === null) {\n throw new AdaptyError({\n adaptyCode: 2002,\n message: 'No view reference',\n });\n }\n\n const dialogConfig = {\n default_action_title: config.primaryActionTitle,\n secondary_action_title: config.secondaryActionTitle,\n title: config.title,\n content: config.content,\n };\n\n const data: Req['AdaptyUIShowDialog.Request'] = {\n method: methodKey,\n id: this.id,\n configuration: dialogConfig,\n };\n\n return await this.adaptyPlugin.handleMethodCall(methodKey, JSON.stringify(data), ctx, log);\n }\n\n private onRequestClose = async () => {\n try {\n await this.dismiss();\n } catch (error) {\n Log.warn(\n 'setEventHandlers',\n () => 'Failed to dismiss paywall',\n () => ({ error }),\n );\n }\n };\n\n /**\n * Registers event handlers for paywall UI events.\n *\n * @remarks\n * Each event type can have only one handler — new handlers replace existing ones.\n * Default handlers are registered automatically in {@link createPaywallView} and provide standard closing behavior:\n * - `onCloseButtonPress` - closes the paywall\n * - `onAndroidSystemBack` - closes the paywall (Android only)\n * - `onRestoreCompleted` - closes the paywall after successful restore\n * - `onPurchaseCompleted` - closes the paywall after successful purchase\n *\n * If you want to override these listeners, we strongly recommend returning `true`\n * (or `purchaseResult.type !== 'user_cancelled'` in case of `onPurchaseCompleted`)\n * from your custom listener to retain default closing behavior.\n *\n * Calling this method multiple times will replace previously registered handlers for provided events.\n *\n * @see {@link https://adapty.io/docs/capacitor-handling-events | Handling View Events}\n *\n * @param eventHandlers - Set of event handling callbacks. Only provided handlers will be registered or updated.\n * @returns A promise that resolves to an unsubscribe function that removes all registered listeners.\n *\n * @example\n * Register custom event handlers\n * ```typescript\n * import { createPaywallView } from '@adapty/capacitor';\n *\n * const view = await createPaywallView(paywall);\n *\n * const unsubscribe = await view.setEventHandlers({\n * onPurchaseStarted: (product) => {\n * console.log('Purchase started:', product.vendorProductId);\n * },\n * onPurchaseCompleted: (result) => {\n * console.log('Purchase completed:', result.type);\n * // Return true to keep default closing behavior\n * return result.type !== 'user_cancelled';\n * },\n * onPurchaseFailed: (error) => {\n * console.error('Purchase failed:', error);\n * }\n * });\n *\n * await view.present();\n *\n * // Later, unsubscribe all handlers\n * unsubscribe();\n * ```\n */\n public async setEventHandlers(eventHandlers: Partial<EventHandlers> = {}): Promise<() => void> {\n const ctx = new LogContext();\n const log = ctx.call({ methodName: 'setEventHandlers' });\n log.start(() => ({ _id: this.id }));\n\n if (this.id === null) {\n throw new AdaptyError({\n adaptyCode: 2002,\n message: 'No view reference',\n });\n }\n\n Log.verbose(\n 'setEventHandlers',\n () => 'Registering event handlers for view',\n () => ({ id: this.id }),\n );\n\n const viewEmitter = this.viewEmitter ?? new PaywallViewEmitter(this.id);\n this.viewEmitter = viewEmitter;\n\n const wrappedErrorLogEventHandlers = mapValues(eventHandlers, (handler, eventName) =>\n handler && typeof handler === 'function'\n ? withErrorContext(handler, eventName as string, 'PaywallViewController')\n : undefined,\n );\n\n // Merge with defaults to ensure default behavior is preserved after unsubscribe/resubscribe cycles\n const finalEventHandlers: EventHandlers = {\n ...DEFAULT_EVENT_HANDLERS,\n ...wrappedErrorLogEventHandlers,\n };\n\n for (const [eventName, handler] of Object.entries(finalEventHandlers)) {\n if (handler && typeof handler === 'function') {\n try {\n await viewEmitter.addListener(eventName as keyof EventHandlers, handler, this.onRequestClose);\n Log.verbose(\n 'setEventHandlers',\n () => 'Registered handler for',\n () => ({ eventName }),\n );\n } catch (error) {\n Log.error(\n 'setEventHandlers',\n () => `Failed to register handler for ${eventName}`,\n () => ({ error }),\n );\n }\n }\n }\n\n // Return unsubscribe function\n const unsubscribe = () => {\n Log.info(\n 'setEventHandlers',\n () => 'Unsubscribing event handlers for view',\n () => ({ id: this.id }),\n );\n if (this.viewEmitter) {\n this.viewEmitter.removeAllListeners();\n this.viewEmitter = null;\n }\n };\n\n return unsubscribe;\n }\n\n /**\n * Clears all registered event handlers.\n *\n * @remarks\n * This method removes all previously registered event handlers.\n * After calling this method, no event handlers will be active\n * until you call {@link setEventHandlers} again.\n *\n * Use this after dismiss to remove all event handlers\n *\n * @example\n * ```typescript\n * const view = await createPaywallView(paywall);\n * await view.setEventHandlers({ onPurchaseCompleted: handlePurchase });\n *\n * // Later, clear all handlers\n * view.clearEventHandlers();\n * ```\n */\n public clearEventHandlers(): void {\n Log.info(\n 'clearEventHandlers',\n () => 'Clearing all event handlers for view',\n () => ({ id: this.id }),\n );\n\n if (this.viewEmitter) {\n this.viewEmitter.removeAllListeners();\n this.viewEmitter = null;\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"paywall-view-controller.js","sourceRoot":"","sources":["../../../src/ui-builder/paywall-view-controller.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Adapty } from '../adapty';\nimport { AdaptyError } from '../shared/adapty-error';\nimport { AdaptyPaywallCoder } from '../shared/coders/adapty-paywall';\nimport { AdaptyUICreatePaywallViewParamsCoder } from '../shared/coders/adapty-ui-create-paywall-view-params';\nimport { LogContext, Log } from '../shared/logger';\nimport type { AdaptyPaywall } from '../shared/types';\nimport type { components } from '../shared/types/api';\nimport { mapValues } from '../shared/utils/map-values';\nimport { withErrorContext } from '../shared/utils/with-error-context';\n\nimport { PaywallViewEmitter } from './paywall-view-emitter';\nimport type {\n AdaptyUiView,\n CreatePaywallViewParamsInput,\n AdaptyUiDialogConfig,\n AdaptyUiDialogActionType,\n EventHandlers,\n AdaptyIOSPresentationStyle,\n} from './types';\nimport { DEFAULT_EVENT_HANDLERS } from './types';\n\ntype Req = components['requests'];\n\nconst DEFAULT_PARAMS: CreatePaywallViewParamsInput = {\n prefetchProducts: true,\n loadTimeoutMs: 5000,\n};\n\n/**\n * Controller for managing paywall views.\n *\n * @remarks\n * This class provides methods to present, dismiss, and handle events for paywall views\n * created with the Paywall Builder. Create instances using the {@link createPaywallView} function\n * rather than directly constructing this class.\n *\n * @public\n */\nexport class PaywallViewController {\n private id: string | null = null;\n private adaptyPlugin: Adapty;\n private viewEmitter: PaywallViewEmitter | null = null;\n\n /**\n * Intended way to create a ViewController instance.\n * It prepares a native controller to be presented\n * and creates reference between native controller and JS instance\n * @internal\n */\n static async create(\n paywall: AdaptyPaywall,\n params: CreatePaywallViewParamsInput,\n adaptyPlugin: Adapty,\n ): Promise<PaywallViewController> {\n const controller = new PaywallViewController(adaptyPlugin);\n\n const ctx = new LogContext();\n const methodKey = 'adapty_ui_create_paywall_view';\n const log = ctx.call({ methodName: methodKey });\n log.start(() => ({ paywall, params }));\n\n const paywallCoder = new AdaptyPaywallCoder();\n const paramsCoder = new AdaptyUICreatePaywallViewParamsCoder();\n const paramsWithDefaults: CreatePaywallViewParamsInput = {\n ...DEFAULT_PARAMS,\n ...params,\n };\n\n const data: Req['AdaptyUICreatePaywallView.Request'] = {\n method: methodKey,\n paywall: paywallCoder.encode(paywall),\n ...paramsCoder.encode(paramsWithDefaults),\n };\n\n const result = (await controller.adaptyPlugin.handleMethodCall(\n methodKey,\n JSON.stringify(data),\n ctx,\n log,\n )) as AdaptyUiView;\n controller.id = result.id;\n controller.viewEmitter = new PaywallViewEmitter(controller.id);\n\n await controller.setEventHandlers(DEFAULT_EVENT_HANDLERS);\n\n return controller;\n }\n\n /**\n * Since constructors in JS cannot be async, it is not\n * preferred to create ViewControllers in direct way.\n * Consider using @link{ViewController.create} instead\n *\n * @internal\n */\n private constructor(adaptyPlugin: Adapty) {\n this.adaptyPlugin = adaptyPlugin;\n }\n\n /**\n * Presents the paywall view as a modal screen.\n *\n * @remarks\n * Calling `present` on an already visible paywall view will result in an error.\n * The paywall will be displayed with the configured presentation style on iOS.\n * On Android, the paywall is always presented as a full-screen activity.\n *\n * @param options - Optional presentation options\n * @param options.iosPresentationStyle - iOS presentation style. Available options: `'full_screen'` (default) or `'page_sheet'`. Only affects iOS platform.\n * @returns A promise that resolves when the paywall is presented.\n * @throws {@link AdaptyError} if the view reference is invalid or the view is already presented.\n *\n * @example\n * Present with default full-screen style\n * ```typescript\n * import { adapty, createPaywallView } from '@adapty/capacitor';\n *\n * const paywall = await adapty.getPaywall({ placementId: 'YOUR_PLACEMENT_ID' });\n * const view = await createPaywallView(paywall);\n * await view.present();\n * ```\n *\n * @example\n * Present with page sheet style on iOS\n * ```typescript\n * await view.present({ iosPresentationStyle: 'page_sheet' });\n * ```\n */\n public async present(options: { iosPresentationStyle?: AdaptyIOSPresentationStyle } = {}): Promise<void> {\n const ctx = new LogContext();\n const methodKey = 'adapty_ui_present_paywall_view';\n const log = ctx.call({ methodName: methodKey });\n log.start(() => ({ _id: this.id, iosPresentationStyle: options.iosPresentationStyle }));\n\n if (this.id === null) {\n throw new AdaptyError({\n adaptyCode: 2002,\n message: 'No view reference',\n });\n }\n\n const data: any = {\n method: methodKey,\n id: this.id,\n ios_presentation_style: options.iosPresentationStyle ?? 'full_screen',\n };\n\n await this.adaptyPlugin.handleMethodCall(methodKey, JSON.stringify(data), ctx, log);\n }\n\n /**\n * Dismisses the paywall view.\n *\n * @remarks\n * This method closes the paywall and cleans up associated resources.\n * After dismissing, the view controller instance cannot be reused.\n *\n * @returns A promise that resolves when the paywall is dismissed.\n * @throws {@link AdaptyError} if the view reference is invalid.\n *\n * @example\n * ```typescript\n * import { createPaywallView } from '@adapty/capacitor';\n *\n * const view = await createPaywallView(paywall);\n * await view.present();\n * // ... later\n * await view.dismiss();\n * ```\n */\n public async dismiss(): Promise<void> {\n const ctx = new LogContext();\n const methodKey = 'adapty_ui_dismiss_paywall_view';\n const log = ctx.call({ methodName: methodKey });\n log.start(() => ({ _id: this.id }));\n\n if (this.id === null) {\n throw new AdaptyError({\n adaptyCode: 2002,\n message: 'No view reference',\n });\n }\n\n const data: Req['AdaptyUIDismissPaywallView.Request'] = {\n method: methodKey,\n id: this.id,\n destroy: true,\n };\n\n await this.adaptyPlugin.handleMethodCall(methodKey, JSON.stringify(data), ctx, log);\n this.clearEventHandlers();\n }\n\n /**\n * Displays a dialog to the user.\n *\n * @remarks\n * Use this method to show custom dialogs within the paywall flow.\n * If you provide two actions in the config, the primary action should cancel the operation\n * and leave things unchanged, while the secondary action should confirm the operation.\n *\n * @param config - Configuration for the dialog.\n * @param config.title - The dialog title.\n * @param config.content - The dialog message content.\n * @param config.primaryActionTitle - The title for the primary (default) action button.\n * @param config.secondaryActionTitle - Optional. The title for the secondary action button.\n * @returns A promise that resolves to the action type that the user selected: `'primary'` or `'secondary'`.\n * @throws {@link AdaptyError} if the view reference is invalid.\n *\n * @example\n * Show confirmation dialog\n * ```typescript\n * const action = await view.showDialog({\n * title: 'Confirm Purchase',\n * content: 'Are you sure you want to proceed with this purchase?',\n * primaryActionTitle: 'Cancel',\n * secondaryActionTitle: 'Continue'\n * });\n *\n * if (action === 'secondary') {\n * console.log('User confirmed');\n * }\n * ```\n */\n public async showDialog(config: AdaptyUiDialogConfig): Promise<AdaptyUiDialogActionType> {\n const ctx = new LogContext();\n const methodKey = 'adapty_ui_show_dialog';\n const log = ctx.call({ methodName: methodKey });\n log.start(() => ({ _id: this.id }));\n\n if (this.id === null) {\n throw new AdaptyError({\n adaptyCode: 2002,\n message: 'No view reference',\n });\n }\n\n const dialogConfig = {\n default_action_title: config.primaryActionTitle,\n secondary_action_title: config.secondaryActionTitle,\n title: config.title,\n content: config.content,\n };\n\n const data: Req['AdaptyUIShowDialog.Request'] = {\n method: methodKey,\n id: this.id,\n configuration: dialogConfig,\n };\n\n return await this.adaptyPlugin.handleMethodCall(methodKey, JSON.stringify(data), ctx, log);\n }\n\n private onRequestClose = async () => {\n try {\n await this.dismiss();\n } catch (error) {\n Log.warn(\n 'setEventHandlers',\n () => 'Failed to dismiss paywall',\n () => ({ error }),\n );\n }\n };\n\n /**\n * Registers event handlers for paywall UI events.\n *\n * @remarks\n * Each event type can have only one handler — new handlers replace existing ones.\n * Default handlers are registered automatically in {@link createPaywallView} and provide standard closing behavior:\n * - `onCloseButtonPress` - closes the paywall\n * - `onAndroidSystemBack` - closes the paywall (Android only)\n * - `onRestoreCompleted` - closes the paywall after successful restore\n * - `onRenderingFailed` - closes the paywall when rendering fails\n * - `onPurchaseCompleted` - closes the paywall after successful purchase\n *\n * If you want to override these listeners, we strongly recommend returning `true`\n * (or `purchaseResult.type !== 'user_cancelled'` in case of `onPurchaseCompleted`)\n * from your custom listener to retain default closing behavior.\n *\n * Calling this method multiple times will replace previously registered handlers for provided events.\n *\n * @see {@link https://adapty.io/docs/capacitor-handling-events | Handling View Events}\n *\n * @param eventHandlers - Set of event handling callbacks. Only provided handlers will be registered or updated.\n * @returns A promise that resolves to an unsubscribe function that removes all registered listeners.\n *\n * @example\n * Register custom event handlers\n * ```typescript\n * import { createPaywallView } from '@adapty/capacitor';\n *\n * const view = await createPaywallView(paywall);\n *\n * const unsubscribe = await view.setEventHandlers({\n * onPurchaseStarted: (product) => {\n * console.log('Purchase started:', product.vendorProductId);\n * },\n * onPurchaseCompleted: (result) => {\n * console.log('Purchase completed:', result.type);\n * // Return true to keep default closing behavior\n * return result.type !== 'user_cancelled';\n * },\n * onPurchaseFailed: (error) => {\n * console.error('Purchase failed:', error);\n * }\n * });\n *\n * await view.present();\n *\n * // Later, unsubscribe all handlers\n * unsubscribe();\n * ```\n */\n public async setEventHandlers(eventHandlers: Partial<EventHandlers> = {}): Promise<() => void> {\n const ctx = new LogContext();\n const log = ctx.call({ methodName: 'setEventHandlers' });\n log.start(() => ({ _id: this.id }));\n\n if (this.id === null) {\n throw new AdaptyError({\n adaptyCode: 2002,\n message: 'No view reference',\n });\n }\n\n Log.verbose(\n 'setEventHandlers',\n () => 'Registering event handlers for view',\n () => ({ id: this.id }),\n );\n\n const viewEmitter = this.viewEmitter ?? new PaywallViewEmitter(this.id);\n this.viewEmitter = viewEmitter;\n\n const wrappedErrorLogEventHandlers = mapValues(eventHandlers, (handler, eventName) =>\n handler && typeof handler === 'function'\n ? withErrorContext(handler, eventName as string, 'PaywallViewController')\n : undefined,\n );\n\n // Merge with defaults to ensure default behavior is preserved after unsubscribe/resubscribe cycles\n const finalEventHandlers: EventHandlers = {\n ...DEFAULT_EVENT_HANDLERS,\n ...wrappedErrorLogEventHandlers,\n };\n\n for (const [eventName, handler] of Object.entries(finalEventHandlers)) {\n if (handler && typeof handler === 'function') {\n try {\n await viewEmitter.addListener(eventName as keyof EventHandlers, handler, this.onRequestClose);\n Log.verbose(\n 'setEventHandlers',\n () => 'Registered handler for',\n () => ({ eventName }),\n );\n } catch (error) {\n Log.error(\n 'setEventHandlers',\n () => `Failed to register handler for ${eventName}`,\n () => ({ error }),\n );\n }\n }\n }\n\n // Return unsubscribe function\n const unsubscribe = () => {\n Log.info(\n 'setEventHandlers',\n () => 'Unsubscribing event handlers for view',\n () => ({ id: this.id }),\n );\n if (this.viewEmitter) {\n this.viewEmitter.removeAllListeners();\n this.viewEmitter = null;\n }\n };\n\n return unsubscribe;\n }\n\n /**\n * Clears all registered event handlers.\n *\n * @remarks\n * This method removes all previously registered event handlers.\n * After calling this method, no event handlers will be active\n * until you call {@link setEventHandlers} again.\n *\n * Use this after dismiss to remove all event handlers\n *\n * @example\n * ```typescript\n * const view = await createPaywallView(paywall);\n * await view.setEventHandlers({ onPurchaseCompleted: handlePurchase });\n *\n * // Later, clear all handlers\n * view.clearEventHandlers();\n * ```\n */\n public clearEventHandlers(): void {\n Log.info(\n 'clearEventHandlers',\n () => 'Clearing all event handlers for view',\n () => ({ id: this.id }),\n );\n\n if (this.viewEmitter) {\n this.viewEmitter.removeAllListeners();\n this.viewEmitter = null;\n }\n }\n}\n"]}
|
|
@@ -1,36 +1,16 @@
|
|
|
1
1
|
import type { LogContext } from '../shared/logger';
|
|
2
|
-
import type {
|
|
3
|
-
import
|
|
4
|
-
import { BaseViewEmitter, type BaseEventConfig } from './base-view-emitter';
|
|
2
|
+
import type { ParsedPaywallEvent, PaywallEventIdType } from '../shared/types/paywall-events';
|
|
3
|
+
import { BaseViewEmitter } from './base-view-emitter';
|
|
5
4
|
import type { EventHandlers } from './types';
|
|
6
|
-
interface ParsedEventData {
|
|
7
|
-
view?: {
|
|
8
|
-
id: string;
|
|
9
|
-
placement_id?: string;
|
|
10
|
-
variation_id?: string;
|
|
11
|
-
};
|
|
12
|
-
action?: {
|
|
13
|
-
type: string;
|
|
14
|
-
value?: unknown;
|
|
15
|
-
};
|
|
16
|
-
product?: AdaptyPaywallProduct;
|
|
17
|
-
product_id?: string;
|
|
18
|
-
purchased_result?: AdaptyPurchaseResult;
|
|
19
|
-
error?: AdaptyError;
|
|
20
|
-
profile?: AdaptyProfile;
|
|
21
|
-
id: string;
|
|
22
|
-
}
|
|
23
5
|
/**
|
|
24
6
|
* PaywallViewEmitter manages event handlers for paywall view events.
|
|
25
7
|
* Each event type can have only one handler - new handlers replace existing ones.
|
|
26
8
|
*/
|
|
27
|
-
export declare class PaywallViewEmitter extends BaseViewEmitter<EventHandlers,
|
|
28
|
-
protected
|
|
29
|
-
protected
|
|
30
|
-
protected
|
|
31
|
-
protected extractCallbackArgs(handlerName: keyof EventHandlers, eventData:
|
|
32
|
-
protected getEventViewId(eventData:
|
|
33
|
-
protected shouldCallHandler(_handlerName: keyof EventHandlers, config: BaseEventConfig, eventData: ParsedEventData): boolean;
|
|
9
|
+
export declare class PaywallViewEmitter extends BaseViewEmitter<EventHandlers, ParsedPaywallEvent, PaywallEventIdType> {
|
|
10
|
+
protected parseEventData(rawEventData: string, ctx: LogContext): ParsedPaywallEvent;
|
|
11
|
+
protected getNativeEventForHandler(event: keyof EventHandlers): PaywallEventIdType | null;
|
|
12
|
+
protected getHandlerForNativeEvent(nativeEvent: PaywallEventIdType, eventData: ParsedPaywallEvent): keyof EventHandlers | null;
|
|
13
|
+
protected extractCallbackArgs(handlerName: keyof EventHandlers, eventData: ParsedPaywallEvent): unknown[];
|
|
14
|
+
protected getEventViewId(eventData: ParsedPaywallEvent): string | null;
|
|
34
15
|
protected getEmitterName(): string;
|
|
35
16
|
}
|
|
36
|
-
export {};
|