react-native-buzzvil-ad 0.1.0
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/Buzzvil.podspec +26 -0
- package/LICENSE +20 -0
- package/README.md +58 -0
- package/android/build.gradle +76 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/com/buzzvil/BuzzvilModule.kt +90 -0
- package/android/src/main/java/com/buzzvil/BuzzvilNativeAdView.kt +250 -0
- package/android/src/main/java/com/buzzvil/BuzzvilNativeAdViewManager.kt +62 -0
- package/android/src/main/java/com/buzzvil/BuzzvilPackage.kt +37 -0
- package/android/src/main/res/layout/buzzvil_native_ad_banner.xml +68 -0
- package/android/src/main/res/layout/buzzvil_native_ad_card.xml +39 -0
- package/ios/Buzzvil.h +5 -0
- package/ios/Buzzvil.mm +100 -0
- package/ios/BuzzvilNativeAdView.h +14 -0
- package/ios/BuzzvilNativeAdView.mm +423 -0
- package/lib/module/BuzzvilNativeAdView.js +16 -0
- package/lib/module/BuzzvilNativeAdView.js.map +1 -0
- package/lib/module/BuzzvilNativeAdView.native.js +42 -0
- package/lib/module/BuzzvilNativeAdView.native.js.map +1 -0
- package/lib/module/BuzzvilNativeAdViewNativeComponent.ts +22 -0
- package/lib/module/NativeBuzzvil.js +32 -0
- package/lib/module/NativeBuzzvil.js.map +1 -0
- package/lib/module/buzzvil.js +25 -0
- package/lib/module/buzzvil.js.map +1 -0
- package/lib/module/buzzvil.native.js +64 -0
- package/lib/module/buzzvil.native.js.map +1 -0
- package/lib/module/index.js +5 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/layout.js +39 -0
- package/lib/module/layout.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/BuzzvilNativeAdView.d.ts +3 -0
- package/lib/typescript/src/BuzzvilNativeAdView.d.ts.map +1 -0
- package/lib/typescript/src/BuzzvilNativeAdView.native.d.ts +196 -0
- package/lib/typescript/src/BuzzvilNativeAdView.native.d.ts.map +1 -0
- package/lib/typescript/src/BuzzvilNativeAdViewNativeComponent.d.ts +25 -0
- package/lib/typescript/src/BuzzvilNativeAdViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/NativeBuzzvil.d.ts +72 -0
- package/lib/typescript/src/NativeBuzzvil.d.ts.map +1 -0
- package/lib/typescript/src/buzzvil.d.ts +7 -0
- package/lib/typescript/src/buzzvil.d.ts.map +1 -0
- package/lib/typescript/src/buzzvil.native.d.ts +25 -0
- package/lib/typescript/src/buzzvil.native.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +5 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/layout.d.ts +6 -0
- package/lib/typescript/src/layout.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +44 -0
- package/lib/typescript/src/types.d.ts.map +1 -0
- package/package.json +159 -0
- package/src/BuzzvilNativeAdView.native.tsx +48 -0
- package/src/BuzzvilNativeAdView.tsx +12 -0
- package/src/BuzzvilNativeAdViewNativeComponent.ts +22 -0
- package/src/NativeBuzzvil.ts +76 -0
- package/src/buzzvil.native.tsx +65 -0
- package/src/buzzvil.tsx +29 -0
- package/src/index.tsx +10 -0
- package/src/layout.ts +21 -0
- package/src/types.ts +45 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { BuzzvilUser, BenefitHubOptions } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Native (iOS/Android) implementation of the public Buzzvil API. Maps the
|
|
4
|
+
* friendly types in `./types` onto the primitive-only native spec, applying
|
|
5
|
+
* the sentinel contract documented in `./NativeBuzzvil`.
|
|
6
|
+
*/
|
|
7
|
+
/** Initialize the BuzzBenefit SDK. Call once, before any other method. */
|
|
8
|
+
export declare function initialize(appId: string): void;
|
|
9
|
+
/**
|
|
10
|
+
* Dev-only sanity checks for `userId`. Buzzvil requires a non-PII, stable,
|
|
11
|
+
* ASCII identifier (≤255 chars) — not an email or login id. Returns a list of
|
|
12
|
+
* human-readable warnings (empty when the id looks fine). Pure: `login` logs
|
|
13
|
+
* these via `console.warn` only under `__DEV__`; it never alters behavior or
|
|
14
|
+
* blocks the call (the SDK is the source of truth on acceptance).
|
|
15
|
+
*/
|
|
16
|
+
export declare function userIdWarnings(userId: string): string[];
|
|
17
|
+
/** Log a user in. Resolves on success, rejects on SDK failure. */
|
|
18
|
+
export declare function login(user: BuzzvilUser): Promise<void>;
|
|
19
|
+
/** Log the current user out. */
|
|
20
|
+
export declare function logout(): void;
|
|
21
|
+
/** Whether a user is currently logged in. */
|
|
22
|
+
export declare function isLoggedIn(): Promise<boolean>;
|
|
23
|
+
/** Present the BenefitHub (offerwall) over the current screen. */
|
|
24
|
+
export declare function showBenefitHub(options?: BenefitHubOptions): void;
|
|
25
|
+
//# sourceMappingURL=buzzvil.native.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buzzvil.native.d.ts","sourceRoot":"","sources":["../../../src/buzzvil.native.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,YAAS,CAAC;AAE9D;;;;GAIG;AAEH,0EAA0E;AAC1E,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAE9C;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAkBvD;AAED,kEAAkE;AAClE,wBAAgB,KAAK,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAOtD;AAED,gCAAgC;AAChC,wBAAgB,MAAM,IAAI,IAAI,CAE7B;AAED,6CAA6C;AAC7C,wBAAgB,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC,CAE7C;AAED,kEAAkE;AAClE,wBAAgB,cAAc,CAAC,OAAO,GAAE,iBAAsB,GAAG,IAAI,CAEpE"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { initialize, login, logout, isLoggedIn, showBenefitHub, } from './buzzvil';
|
|
2
|
+
export type { BuzzvilUser, BuzzvilGender, BenefitHubOptions } from './types.js';
|
|
3
|
+
export { BuzzvilNativeAdView } from './BuzzvilNativeAdView';
|
|
4
|
+
export type { BuzzvilNativeAdLayout, BuzzvilNativeAdViewProps } from './types.js';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,KAAK,EACL,MAAM,EACN,UAAU,EACV,cAAc,GACf,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,YAAS,CAAC;AAC7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,YAAS,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../src/layout.ts"],"names":[],"mappings":"AAiBA,4EAA4E;AAC5E,wBAAgB,aAAa,CAAC,MAAM,CAAC,EAAE,MAAM;WATF,MAAM;YAAU,MAAM;cAWhE"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public, friendly types for the Buzzvil wrapper. These are the types
|
|
3
|
+
* consumers see; the native spec (`./NativeBuzzvil`) uses primitives only and
|
|
4
|
+
* the wrapper (`./buzzvil.native.tsx`) maps between the two.
|
|
5
|
+
*/
|
|
6
|
+
/** Optional demographic hint used by Buzzvil for ad targeting. */
|
|
7
|
+
export type BuzzvilGender = 'MALE' | 'FEMALE';
|
|
8
|
+
/** A Buzzvil user. Only `userId` is required; the rest improve targeting. */
|
|
9
|
+
export interface BuzzvilUser {
|
|
10
|
+
/** Non-identifiable, persistent user id. ASCII, max 255 chars. */
|
|
11
|
+
userId: string;
|
|
12
|
+
gender?: BuzzvilGender;
|
|
13
|
+
/** 4-digit birth year, e.g. `1990`. */
|
|
14
|
+
birthYear?: number;
|
|
15
|
+
}
|
|
16
|
+
/** Options for presenting the BenefitHub (offerwall). */
|
|
17
|
+
export interface BenefitHubOptions {
|
|
18
|
+
/** BenefitHub page number from the Buzzvil admin (advanced routing). */
|
|
19
|
+
routePath?: string;
|
|
20
|
+
/** Open directly on the history/earnings page instead of the default hub. */
|
|
21
|
+
showHistory?: boolean;
|
|
22
|
+
}
|
|
23
|
+
/** Supported Native-ad layout sizes (width x height in dp). */
|
|
24
|
+
export type BuzzvilNativeAdLayout = '320x50' | '320x100' | '320x130' | '300x250' | '320x480';
|
|
25
|
+
/** Friendly props for the `BuzzvilNativeAdView` Fabric component. */
|
|
26
|
+
export interface BuzzvilNativeAdViewProps {
|
|
27
|
+
unitId: string;
|
|
28
|
+
layout?: BuzzvilNativeAdLayout;
|
|
29
|
+
style?: import('react-native').StyleProp<import('react-native').ViewStyle>;
|
|
30
|
+
onAdLoaded?: (e: {
|
|
31
|
+
width: number;
|
|
32
|
+
height: number;
|
|
33
|
+
}) => void;
|
|
34
|
+
onAdFailed?: (e: {
|
|
35
|
+
code: string;
|
|
36
|
+
message: string;
|
|
37
|
+
}) => void;
|
|
38
|
+
onAdClicked?: () => void;
|
|
39
|
+
onImpressed?: () => void;
|
|
40
|
+
onRewarded?: (e: {
|
|
41
|
+
success: boolean;
|
|
42
|
+
}) => void;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,kEAAkE;AAClE,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE9C,6EAA6E;AAC7E,MAAM,WAAW,WAAW;IAC1B,kEAAkE;IAClE,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,uCAAuC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,yDAAyD;AACzD,MAAM,WAAW,iBAAiB;IAChC,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6EAA6E;IAC7E,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,+DAA+D;AAC/D,MAAM,MAAM,qBAAqB,GAC7B,QAAQ,GACR,SAAS,GACT,SAAS,GACT,SAAS,GACT,SAAS,CAAC;AAEd,qEAAqE;AACrE,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,qBAAqB,CAAC;IAC/B,KAAK,CAAC,EAAE,OAAO,cAAc,EAAE,SAAS,CAAC,OAAO,cAAc,EAAE,SAAS,CAAC,CAAC;IAC3E,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC5D,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC5D,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;CAChD"}
|
package/package.json
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "react-native-buzzvil-ad",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Unofficial, community-maintained React Native wrapper for the Buzzvil BuzzBenefit SDK (Android & iOS). Not affiliated with, endorsed by, or supported by Buzzvil.",
|
|
5
|
+
"main": "./lib/module/index.js",
|
|
6
|
+
"types": "./lib/typescript/src/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"source": "./src/index.tsx",
|
|
10
|
+
"types": "./lib/typescript/src/index.d.ts",
|
|
11
|
+
"default": "./lib/module/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./package.json": "./package.json"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"src",
|
|
17
|
+
"lib",
|
|
18
|
+
"android",
|
|
19
|
+
"ios",
|
|
20
|
+
"cpp",
|
|
21
|
+
"*.podspec",
|
|
22
|
+
"react-native.config.js",
|
|
23
|
+
"!ios/build",
|
|
24
|
+
"!android/build",
|
|
25
|
+
"!android/gradle",
|
|
26
|
+
"!android/gradlew",
|
|
27
|
+
"!android/gradlew.bat",
|
|
28
|
+
"!android/local.properties",
|
|
29
|
+
"!**/__tests__",
|
|
30
|
+
"!**/__fixtures__",
|
|
31
|
+
"!**/__mocks__",
|
|
32
|
+
"!**/.*"
|
|
33
|
+
],
|
|
34
|
+
"scripts": {
|
|
35
|
+
"example": "yarn workspace react-native-buzzvil-example",
|
|
36
|
+
"clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib",
|
|
37
|
+
"prepare": "bob build",
|
|
38
|
+
"typecheck": "tsc",
|
|
39
|
+
"lint": "eslint \"**/*.{js,ts,tsx}\"",
|
|
40
|
+
"test": "jest",
|
|
41
|
+
"web": "vite",
|
|
42
|
+
"build:web": "vite build"
|
|
43
|
+
},
|
|
44
|
+
"keywords": [
|
|
45
|
+
"react-native",
|
|
46
|
+
"ios",
|
|
47
|
+
"android"
|
|
48
|
+
],
|
|
49
|
+
"repository": {
|
|
50
|
+
"type": "git",
|
|
51
|
+
"url": "git+https://github.com/AndrewDongminYoo/react-native-buzzvil.git"
|
|
52
|
+
},
|
|
53
|
+
"author": "Dongmin, Yu <ydm2790@gmail.com> (https://github.com/AndrewDongminYoo)",
|
|
54
|
+
"license": "MIT",
|
|
55
|
+
"bugs": {
|
|
56
|
+
"url": "https://github.com/AndrewDongminYoo/react-native-buzzvil/issues"
|
|
57
|
+
},
|
|
58
|
+
"homepage": "https://github.com/AndrewDongminYoo/react-native-buzzvil#readme",
|
|
59
|
+
"publishConfig": {
|
|
60
|
+
"access": "public",
|
|
61
|
+
"registry": "https://registry.npmjs.org/"
|
|
62
|
+
},
|
|
63
|
+
"devDependencies": {
|
|
64
|
+
"@eslint/compat": "^2.1.0",
|
|
65
|
+
"@eslint/eslintrc": "^3.3.5",
|
|
66
|
+
"@eslint/js": "^10.0.1",
|
|
67
|
+
"@jest/globals": "^30.0.0",
|
|
68
|
+
"@react-native/babel-preset": "0.85.0",
|
|
69
|
+
"@react-native/eslint-config": "0.85.0",
|
|
70
|
+
"@react-native/jest-preset": "0.85.0",
|
|
71
|
+
"@types/react": "^19.2.0",
|
|
72
|
+
"del-cli": "^7.0.0",
|
|
73
|
+
"eslint": "^9.39.4",
|
|
74
|
+
"eslint-config-prettier": "^10.1.8",
|
|
75
|
+
"eslint-plugin-ft-flow": "^3.0.11",
|
|
76
|
+
"eslint-plugin-prettier": "^5.5.6",
|
|
77
|
+
"jest": "^30.3.0",
|
|
78
|
+
"prettier": "^3.8.3",
|
|
79
|
+
"react": "19.2.3",
|
|
80
|
+
"react-native": "0.85.0",
|
|
81
|
+
"react-native-builder-bob": "^0.42.1",
|
|
82
|
+
"react-native-web": "~0.21.2",
|
|
83
|
+
"turbo": "^2.9.16",
|
|
84
|
+
"typescript": "^6.0.3"
|
|
85
|
+
},
|
|
86
|
+
"peerDependencies": {
|
|
87
|
+
"react": "*",
|
|
88
|
+
"react-native": "*"
|
|
89
|
+
},
|
|
90
|
+
"resolutions": {
|
|
91
|
+
"jest": "30.4.1",
|
|
92
|
+
"jest-cli": "30.4.1",
|
|
93
|
+
"@jest/core": "30.4.1",
|
|
94
|
+
"jest-runtime": "30.4.1",
|
|
95
|
+
"jest-mock": "30.4.1",
|
|
96
|
+
"jest-environment-node": "30.4.1"
|
|
97
|
+
},
|
|
98
|
+
"workspaces": [
|
|
99
|
+
"example"
|
|
100
|
+
],
|
|
101
|
+
"packageManager": "yarn@4.11.0",
|
|
102
|
+
"react-native-builder-bob": {
|
|
103
|
+
"source": "src",
|
|
104
|
+
"output": "lib",
|
|
105
|
+
"targets": [
|
|
106
|
+
[
|
|
107
|
+
"module",
|
|
108
|
+
{
|
|
109
|
+
"esm": true
|
|
110
|
+
}
|
|
111
|
+
],
|
|
112
|
+
[
|
|
113
|
+
"typescript",
|
|
114
|
+
{
|
|
115
|
+
"project": "tsconfig.build.json"
|
|
116
|
+
}
|
|
117
|
+
]
|
|
118
|
+
]
|
|
119
|
+
},
|
|
120
|
+
"codegenConfig": {
|
|
121
|
+
"name": "BuzzvilSpec",
|
|
122
|
+
"type": "all",
|
|
123
|
+
"jsSrcsDir": "src",
|
|
124
|
+
"android": {
|
|
125
|
+
"javaPackageName": "com.buzzvil"
|
|
126
|
+
},
|
|
127
|
+
"ios": {
|
|
128
|
+
"components": {
|
|
129
|
+
"BuzzvilNativeAdView": {
|
|
130
|
+
"className": "BuzzvilNativeAdView"
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
"prettier": {
|
|
136
|
+
"quoteProps": "consistent",
|
|
137
|
+
"singleQuote": true,
|
|
138
|
+
"tabWidth": 2,
|
|
139
|
+
"trailingComma": "es5",
|
|
140
|
+
"useTabs": false
|
|
141
|
+
},
|
|
142
|
+
"jest": {
|
|
143
|
+
"preset": "@react-native/jest-preset",
|
|
144
|
+
"modulePathIgnorePatterns": [
|
|
145
|
+
"<rootDir>/example/node_modules",
|
|
146
|
+
"<rootDir>/lib/"
|
|
147
|
+
]
|
|
148
|
+
},
|
|
149
|
+
"create-react-native-library": {
|
|
150
|
+
"type": "fabric-view",
|
|
151
|
+
"languages": "kotlin-objc",
|
|
152
|
+
"tools": [
|
|
153
|
+
"eslint",
|
|
154
|
+
"jest",
|
|
155
|
+
"vite"
|
|
156
|
+
],
|
|
157
|
+
"version": "0.62.2"
|
|
158
|
+
}
|
|
159
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import NativeComponent from './BuzzvilNativeAdViewNativeComponent';
|
|
2
|
+
import { sizeForLayout } from './layout';
|
|
3
|
+
import type { BuzzvilNativeAdViewProps } from './types';
|
|
4
|
+
|
|
5
|
+
export { sizeForLayout };
|
|
6
|
+
|
|
7
|
+
const DEFAULT_LAYOUT = '300x250';
|
|
8
|
+
|
|
9
|
+
export function toNativeProps(props: BuzzvilNativeAdViewProps) {
|
|
10
|
+
const {
|
|
11
|
+
layout,
|
|
12
|
+
onAdLoaded,
|
|
13
|
+
onAdFailed,
|
|
14
|
+
onAdClicked,
|
|
15
|
+
onImpressed,
|
|
16
|
+
onRewarded,
|
|
17
|
+
...rest
|
|
18
|
+
} = props;
|
|
19
|
+
return {
|
|
20
|
+
...rest,
|
|
21
|
+
layout: layout ?? DEFAULT_LAYOUT,
|
|
22
|
+
onAdLoaded: onAdLoaded
|
|
23
|
+
? (e: { nativeEvent: { width: number; height: number } }) =>
|
|
24
|
+
onAdLoaded(e.nativeEvent)
|
|
25
|
+
: undefined,
|
|
26
|
+
onAdFailed: onAdFailed
|
|
27
|
+
? (e: { nativeEvent: { code: string; message: string } }) =>
|
|
28
|
+
onAdFailed(e.nativeEvent)
|
|
29
|
+
: undefined,
|
|
30
|
+
// No payload — pass the friendly handler straight through (it ignores the
|
|
31
|
+
// native event arg). Avoids an empty wrapper that could mislead a future
|
|
32
|
+
// contributor copying the pattern for a payload-carrying event.
|
|
33
|
+
onAdClicked,
|
|
34
|
+
onImpressed,
|
|
35
|
+
onRewarded: onRewarded
|
|
36
|
+
? (e: { nativeEvent: { success: boolean } }) => onRewarded(e.nativeEvent)
|
|
37
|
+
: undefined,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function BuzzvilNativeAdView(props: BuzzvilNativeAdViewProps) {
|
|
42
|
+
const native = toNativeProps(props);
|
|
43
|
+
const size = sizeForLayout(props.layout);
|
|
44
|
+
// Apply the inventory size as a DEFAULT style; the consumer's `style` is
|
|
45
|
+
// last in the array, so it overrides. `style` is set once here (the explicit
|
|
46
|
+
// prop wins over the one carried in `native`'s spread).
|
|
47
|
+
return <NativeComponent {...(native as any)} style={[size, props.style]} />;
|
|
48
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { View } from 'react-native';
|
|
2
|
+
import { sizeForLayout } from './layout';
|
|
3
|
+
import type { BuzzvilNativeAdViewProps } from './types';
|
|
4
|
+
|
|
5
|
+
export function BuzzvilNativeAdView({
|
|
6
|
+
layout,
|
|
7
|
+
style,
|
|
8
|
+
}: BuzzvilNativeAdViewProps) {
|
|
9
|
+
// Buzzvil native ads are not available on web; render nothing visible, but
|
|
10
|
+
// reserve the same box as native (consumer `style` overrides the default).
|
|
11
|
+
return <View style={[sizeForLayout(layout), style]} />;
|
|
12
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { codegenNativeComponent, type ViewProps } from 'react-native';
|
|
2
|
+
import type { CodegenTypes } from 'react-native';
|
|
3
|
+
|
|
4
|
+
// Flat primitive payloads — codegen events cannot carry nested objects/enums.
|
|
5
|
+
type AdLoadedEvent = Readonly<{
|
|
6
|
+
width: CodegenTypes.Double;
|
|
7
|
+
height: CodegenTypes.Double;
|
|
8
|
+
}>;
|
|
9
|
+
type AdFailedEvent = Readonly<{ code: string; message: string }>;
|
|
10
|
+
type RewardedEvent = Readonly<{ success: boolean }>;
|
|
11
|
+
|
|
12
|
+
export interface NativeProps extends ViewProps {
|
|
13
|
+
unitId: string;
|
|
14
|
+
layout?: string; // friendly union + default live in the JS wrapper; codegen sees a plain string
|
|
15
|
+
onAdLoaded?: CodegenTypes.DirectEventHandler<AdLoadedEvent>;
|
|
16
|
+
onAdFailed?: CodegenTypes.DirectEventHandler<AdFailedEvent>;
|
|
17
|
+
onAdClicked?: CodegenTypes.DirectEventHandler<Readonly<{}>>;
|
|
18
|
+
onImpressed?: CodegenTypes.DirectEventHandler<Readonly<{}>>;
|
|
19
|
+
onRewarded?: CodegenTypes.DirectEventHandler<RewardedEvent>;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default codegenNativeComponent<NativeProps>('BuzzvilNativeAdView');
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { TurboModuleRegistry, type TurboModule } from 'react-native';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* TurboModule spec for the native `Buzzvil` module — a thin bridge over
|
|
5
|
+
* Buzzvil's BuzzBenefit v6 SDKs (Android / iOS).
|
|
6
|
+
*
|
|
7
|
+
* This file is the **source of truth**: codegen generates the native
|
|
8
|
+
* interfaces from it. The codegen type system is restricted, so the spec
|
|
9
|
+
* intentionally uses **primitives only** — no optional fields, no object
|
|
10
|
+
* params, no enums/unions. Friendly types (optional fields, the `'MALE' |
|
|
11
|
+
* 'FEMALE'` gender union) live in `./types` and are applied in the JS
|
|
12
|
+
* wrapper (`./buzzvil.native.tsx`).
|
|
13
|
+
*
|
|
14
|
+
* ## Sentinel contract (MUST be interpreted identically by both native impls)
|
|
15
|
+
*
|
|
16
|
+
* Because the spec has no optionals, the JS wrapper encodes "not provided"
|
|
17
|
+
* as sentinel values. `BuzzvilModule.kt` and `Buzzvil.mm` must treat them
|
|
18
|
+
* the same way or the platforms will silently diverge:
|
|
19
|
+
*
|
|
20
|
+
* - `gender`: `'MALE'` or `'FEMALE'`. **Empty string `''` → do not set gender**
|
|
21
|
+
* (pass `null` to the native user builder).
|
|
22
|
+
* - `birthYear`: a 4-digit year. **`0` → do not set birth year** (pass `null`).
|
|
23
|
+
* - `routePath`: a BenefitHub page number from the Buzzvil admin. **`''` → no
|
|
24
|
+
* route path** (open the default hub page).
|
|
25
|
+
* - `showHistory`: `true` → open the BenefitHub history/earnings page
|
|
26
|
+
* (Android `BuzzBenefitHubPage.HISTORY` / iOS `.history` query params).
|
|
27
|
+
*/
|
|
28
|
+
export interface Spec extends TurboModule {
|
|
29
|
+
/**
|
|
30
|
+
* Initialize the BuzzBenefit SDK with the app's Buzzvil app id.
|
|
31
|
+
*
|
|
32
|
+
* - iOS: `BuzzBenefit.shared.initialize(with: BuzzBenefitConfig.Builder(appId:).build())`.
|
|
33
|
+
* - Android: `BuzzvilSdk.initialize(application, BuzzBenefitConfig.Builder(appId).build())`.
|
|
34
|
+
*
|
|
35
|
+
* NOTE (verify at native-impl time): the Android SDK initializes with the
|
|
36
|
+
* `Application` instance and the docs recommend `Application.onCreate()`
|
|
37
|
+
* timing. JS-driven init must pass `reactContext.applicationContext as
|
|
38
|
+
* Application` and run before any `login`/`showBenefitHub` call. If the
|
|
39
|
+
* Android SDK turns out to require manifest/Application-level setup (as the
|
|
40
|
+
* AdPopcorn wrapper's `setAppKey` does), this becomes iOS-effective with an
|
|
41
|
+
* Android no-op — confirm against the running SDK before shipping.
|
|
42
|
+
*/
|
|
43
|
+
initialize(appId: string): void;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Log a user into the SDK. Resolves on success, rejects on failure.
|
|
47
|
+
*
|
|
48
|
+
* See the sentinel contract above for `gender` / `birthYear`.
|
|
49
|
+
*
|
|
50
|
+
* - iOS: `BuzzBenefit.shared.login(with:onSuccess:onFailure:)`.
|
|
51
|
+
* - Android: `BuzzvilSdk.login(BuzzvilSdkUser(...), BuzzvilSdkLoginListener)`.
|
|
52
|
+
*
|
|
53
|
+
* @param userId Non-identifiable, persistent user id. ASCII, max 255 chars.
|
|
54
|
+
* @param gender `'MALE'` | `'FEMALE'` | `''` (unset).
|
|
55
|
+
* @param birthYear 4-digit year, or `0` (unset).
|
|
56
|
+
*/
|
|
57
|
+
login(userId: string, gender: string, birthYear: number): Promise<void>;
|
|
58
|
+
|
|
59
|
+
/** Log the current user out. iOS/Android: `logout()`. */
|
|
60
|
+
logout(): void;
|
|
61
|
+
|
|
62
|
+
/** Whether a user is currently logged in. iOS `isLoggedIn()` / Android `isLoggedIn`. */
|
|
63
|
+
isLoggedIn(): Promise<boolean>;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Present the BenefitHub (offerwall) over the current screen.
|
|
67
|
+
*
|
|
68
|
+
* - iOS: `BuzzBenefitHub().show(on: currentViewController)`.
|
|
69
|
+
* - Android: `BuzzBenefitHub.show(currentActivity, config)`.
|
|
70
|
+
*
|
|
71
|
+
* See the sentinel contract above for `routePath` / `showHistory`.
|
|
72
|
+
*/
|
|
73
|
+
showBenefitHub(routePath: string, showHistory: boolean): void;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export default TurboModuleRegistry.getEnforcing<Spec>('Buzzvil');
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import Buzzvil from './NativeBuzzvil';
|
|
2
|
+
import type { BuzzvilUser, BenefitHubOptions } from './types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Native (iOS/Android) implementation of the public Buzzvil API. Maps the
|
|
6
|
+
* friendly types in `./types` onto the primitive-only native spec, applying
|
|
7
|
+
* the sentinel contract documented in `./NativeBuzzvil`.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** Initialize the BuzzBenefit SDK. Call once, before any other method. */
|
|
11
|
+
export function initialize(appId: string): void {
|
|
12
|
+
Buzzvil.initialize(appId);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Dev-only sanity checks for `userId`. Buzzvil requires a non-PII, stable,
|
|
17
|
+
* ASCII identifier (≤255 chars) — not an email or login id. Returns a list of
|
|
18
|
+
* human-readable warnings (empty when the id looks fine). Pure: `login` logs
|
|
19
|
+
* these via `console.warn` only under `__DEV__`; it never alters behavior or
|
|
20
|
+
* blocks the call (the SDK is the source of truth on acceptance).
|
|
21
|
+
*/
|
|
22
|
+
export function userIdWarnings(userId: string): string[] {
|
|
23
|
+
const warnings: string[] = [];
|
|
24
|
+
if (!userId) {
|
|
25
|
+
warnings.push('userId is empty.');
|
|
26
|
+
return warnings;
|
|
27
|
+
}
|
|
28
|
+
if (userId.includes('@')) {
|
|
29
|
+
warnings.push(
|
|
30
|
+
'userId looks like an email — Buzzvil requires a non-PII, stable identifier (not an email/login id); ads may be rejected.'
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
if (userId.length > 255) {
|
|
34
|
+
warnings.push('userId exceeds 255 characters.');
|
|
35
|
+
}
|
|
36
|
+
if ([...userId].some((ch) => ch.charCodeAt(0) > 127)) {
|
|
37
|
+
warnings.push('userId should be ASCII.');
|
|
38
|
+
}
|
|
39
|
+
return warnings;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Log a user in. Resolves on success, rejects on SDK failure. */
|
|
43
|
+
export function login(user: BuzzvilUser): Promise<void> {
|
|
44
|
+
if (__DEV__) {
|
|
45
|
+
for (const message of userIdWarnings(user.userId)) {
|
|
46
|
+
console.warn(`[buzzvil] login: ${message}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return Buzzvil.login(user.userId, user.gender ?? '', user.birthYear ?? 0);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Log the current user out. */
|
|
53
|
+
export function logout(): void {
|
|
54
|
+
Buzzvil.logout();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Whether a user is currently logged in. */
|
|
58
|
+
export function isLoggedIn(): Promise<boolean> {
|
|
59
|
+
return Buzzvil.isLoggedIn();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Present the BenefitHub (offerwall) over the current screen. */
|
|
63
|
+
export function showBenefitHub(options: BenefitHubOptions = {}): void {
|
|
64
|
+
Buzzvil.showBenefitHub(options.routePath ?? '', options.showHistory ?? false);
|
|
65
|
+
}
|
package/src/buzzvil.tsx
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { BuzzvilUser, BenefitHubOptions } from './types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Web fallback. Buzzvil's BuzzBenefit SDKs are mobile-only, so every method
|
|
5
|
+
* throws **at call time** (never at import time — importing must not break the
|
|
6
|
+
* web bundle). The `.native.tsx` counterpart is used on iOS/Android.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const UNSUPPORTED = 'react-native-buzzvil is not supported on web.';
|
|
10
|
+
|
|
11
|
+
export function initialize(_appId: string): void {
|
|
12
|
+
throw new Error(UNSUPPORTED);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function login(_user: BuzzvilUser): Promise<void> {
|
|
16
|
+
return Promise.reject(new Error(UNSUPPORTED));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function logout(): void {
|
|
20
|
+
throw new Error(UNSUPPORTED);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function isLoggedIn(): Promise<boolean> {
|
|
24
|
+
return Promise.reject(new Error(UNSUPPORTED));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function showBenefitHub(_options: BenefitHubOptions = {}): void {
|
|
28
|
+
throw new Error(UNSUPPORTED);
|
|
29
|
+
}
|
package/src/index.tsx
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export {
|
|
2
|
+
initialize,
|
|
3
|
+
login,
|
|
4
|
+
logout,
|
|
5
|
+
isLoggedIn,
|
|
6
|
+
showBenefitHub,
|
|
7
|
+
} from './buzzvil';
|
|
8
|
+
export type { BuzzvilUser, BuzzvilGender, BenefitHubOptions } from './types';
|
|
9
|
+
export { BuzzvilNativeAdView } from './BuzzvilNativeAdView';
|
|
10
|
+
export type { BuzzvilNativeAdLayout, BuzzvilNativeAdViewProps } from './types';
|
package/src/layout.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default inventory sizes for the Native-ad layout variants, shared by the
|
|
3
|
+
* native and web `BuzzvilNativeAdView` so the box matches on every platform.
|
|
4
|
+
*
|
|
5
|
+
* Under Fabric the component's frame comes from the JS shadow node (the
|
|
6
|
+
* `style`), so the native side's per-size height is only a hint — without a
|
|
7
|
+
* JS-side height iOS bounds stay 0 and `onAdLoaded` never fires. The wrapper
|
|
8
|
+
* therefore applies one of these as a DEFAULT style; a consumer `style` wins.
|
|
9
|
+
*/
|
|
10
|
+
const LAYOUT_SIZE: Record<string, { width: number; height: number }> = {
|
|
11
|
+
'320x50': { width: 320, height: 50 },
|
|
12
|
+
'320x100': { width: 320, height: 100 },
|
|
13
|
+
'320x130': { width: 320, height: 130 },
|
|
14
|
+
'300x250': { width: 300, height: 250 },
|
|
15
|
+
'320x480': { width: 320, height: 480 },
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/** Resolve the default size for a layout; unknown/undefined → `300x250`. */
|
|
19
|
+
export function sizeForLayout(layout?: string) {
|
|
20
|
+
return LAYOUT_SIZE[layout ?? '300x250'] ?? LAYOUT_SIZE['300x250'];
|
|
21
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public, friendly types for the Buzzvil wrapper. These are the types
|
|
3
|
+
* consumers see; the native spec (`./NativeBuzzvil`) uses primitives only and
|
|
4
|
+
* the wrapper (`./buzzvil.native.tsx`) maps between the two.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/** Optional demographic hint used by Buzzvil for ad targeting. */
|
|
8
|
+
export type BuzzvilGender = 'MALE' | 'FEMALE';
|
|
9
|
+
|
|
10
|
+
/** A Buzzvil user. Only `userId` is required; the rest improve targeting. */
|
|
11
|
+
export interface BuzzvilUser {
|
|
12
|
+
/** Non-identifiable, persistent user id. ASCII, max 255 chars. */
|
|
13
|
+
userId: string;
|
|
14
|
+
gender?: BuzzvilGender;
|
|
15
|
+
/** 4-digit birth year, e.g. `1990`. */
|
|
16
|
+
birthYear?: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Options for presenting the BenefitHub (offerwall). */
|
|
20
|
+
export interface BenefitHubOptions {
|
|
21
|
+
/** BenefitHub page number from the Buzzvil admin (advanced routing). */
|
|
22
|
+
routePath?: string;
|
|
23
|
+
/** Open directly on the history/earnings page instead of the default hub. */
|
|
24
|
+
showHistory?: boolean;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Supported Native-ad layout sizes (width x height in dp). */
|
|
28
|
+
export type BuzzvilNativeAdLayout =
|
|
29
|
+
| '320x50'
|
|
30
|
+
| '320x100'
|
|
31
|
+
| '320x130'
|
|
32
|
+
| '300x250'
|
|
33
|
+
| '320x480';
|
|
34
|
+
|
|
35
|
+
/** Friendly props for the `BuzzvilNativeAdView` Fabric component. */
|
|
36
|
+
export interface BuzzvilNativeAdViewProps {
|
|
37
|
+
unitId: string;
|
|
38
|
+
layout?: BuzzvilNativeAdLayout;
|
|
39
|
+
style?: import('react-native').StyleProp<import('react-native').ViewStyle>;
|
|
40
|
+
onAdLoaded?: (e: { width: number; height: number }) => void;
|
|
41
|
+
onAdFailed?: (e: { code: string; message: string }) => void;
|
|
42
|
+
onAdClicked?: () => void;
|
|
43
|
+
onImpressed?: () => void;
|
|
44
|
+
onRewarded?: (e: { success: boolean }) => void;
|
|
45
|
+
}
|