@purchasely/cordova-plugin-purchasely 2.3.1 → 4.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/example/android.sh +8 -0
- package/example/config.xml +1 -1
- package/example/ios.sh +16 -0
- package/example/package-lock.json +410 -482
- package/example/package.json +5 -4
- package/example/www/index.html +12 -0
- package/example/www/js/index.js +113 -9
- package/package.json +9 -1
- package/plugin.xml +16 -5
- package/purchasely.iml +11 -0
- package/src/android/PLYProductActivity.kt +171 -0
- package/src/android/PLYSubscriptionsActivity.java +1 -1
- package/src/android/PurchaselyPlugin.kt +916 -0
- package/src/android/activity_ply_product_activity.xml +2 -2
- package/src/android/activity_ply_subscriptions_activity.xml +6 -0
- package/src/ios/CDVPurchasely.h +23 -6
- package/src/ios/CDVPurchasely.m +432 -35
- package/src/ios/Hybrid/PLYPlan+Hybrid.m +0 -1
- package/src/ios/Hybrid/PLYPresentationPlan+Hybrid.h +20 -0
- package/src/ios/Hybrid/PLYPresentationPlan+Hybrid.m +31 -0
- package/src/ios/Hybrid/Purchasely_Hybrid.h +1 -0
- package/src/ios/Hybrid/UIColor+PLYHelper.h +19 -0
- package/src/ios/Hybrid/UIColor+PLYHelper.m +66 -0
- package/www/Purchasely.js +90 -28
- package/src/android/PLYProductActivity.java +0 -87
- package/src/android/PurchaselyPlugin.java +0 -739
|
@@ -0,0 +1,916 @@
|
|
|
1
|
+
package cordova.plugin.purchasely
|
|
2
|
+
|
|
3
|
+
import android.app.Activity
|
|
4
|
+
import android.content.Intent
|
|
5
|
+
import android.net.Uri
|
|
6
|
+
import android.os.Build
|
|
7
|
+
import android.util.Log
|
|
8
|
+
import io.purchasely.billing.Store
|
|
9
|
+
import io.purchasely.ext.Attribute
|
|
10
|
+
import io.purchasely.ext.DistributionType
|
|
11
|
+
import io.purchasely.ext.EventListener
|
|
12
|
+
import io.purchasely.ext.LogLevel
|
|
13
|
+
import io.purchasely.ext.PLYAppTechnology
|
|
14
|
+
import io.purchasely.ext.PLYCompletionHandler
|
|
15
|
+
import io.purchasely.ext.PLYEvent
|
|
16
|
+
import io.purchasely.ext.PLYPresentation
|
|
17
|
+
import io.purchasely.ext.PLYPresentationAction
|
|
18
|
+
import io.purchasely.ext.PLYPresentationType
|
|
19
|
+
import io.purchasely.ext.PLYPresentationViewProperties
|
|
20
|
+
import io.purchasely.ext.PLYProductViewResult
|
|
21
|
+
import io.purchasely.ext.PLYRunningMode
|
|
22
|
+
import io.purchasely.ext.PLYRunningMode.Full
|
|
23
|
+
import io.purchasely.ext.PLYRunningMode.PaywallObserver
|
|
24
|
+
import io.purchasely.ext.PlanListener
|
|
25
|
+
import io.purchasely.ext.ProductListener
|
|
26
|
+
import io.purchasely.ext.ProductsListener
|
|
27
|
+
import io.purchasely.ext.PurchaseListener
|
|
28
|
+
import io.purchasely.ext.Purchasely
|
|
29
|
+
import io.purchasely.ext.State
|
|
30
|
+
import io.purchasely.ext.StoreType
|
|
31
|
+
import io.purchasely.ext.SubscriptionsListener
|
|
32
|
+
import io.purchasely.models.PLYError
|
|
33
|
+
import io.purchasely.models.PLYPlan
|
|
34
|
+
import io.purchasely.models.PLYPresentationPlan
|
|
35
|
+
import io.purchasely.models.PLYProduct
|
|
36
|
+
import io.purchasely.models.PLYSubscriptionData
|
|
37
|
+
import org.apache.cordova.CallbackContext
|
|
38
|
+
import org.apache.cordova.CordovaInterface
|
|
39
|
+
import org.apache.cordova.CordovaPlugin
|
|
40
|
+
import org.apache.cordova.PluginResult
|
|
41
|
+
import org.json.JSONArray
|
|
42
|
+
import org.json.JSONException
|
|
43
|
+
import org.json.JSONObject
|
|
44
|
+
import java.lang.ref.WeakReference
|
|
45
|
+
import java.text.SimpleDateFormat
|
|
46
|
+
import java.util.Calendar
|
|
47
|
+
import java.util.Date
|
|
48
|
+
import java.util.Locale
|
|
49
|
+
import java.util.TimeZone
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* This class echoes a string called from JavaScript.
|
|
53
|
+
*/
|
|
54
|
+
class PurchaselyPlugin : CordovaPlugin() {
|
|
55
|
+
private var paywallActionHandler: PLYCompletionHandler? = null
|
|
56
|
+
private var paywallAction: PLYPresentationAction? = null
|
|
57
|
+
|
|
58
|
+
override fun execute(
|
|
59
|
+
action: String,
|
|
60
|
+
args: JSONArray,
|
|
61
|
+
callbackContext: CallbackContext
|
|
62
|
+
): Boolean {
|
|
63
|
+
try {
|
|
64
|
+
when (action) {
|
|
65
|
+
"start" -> start(
|
|
66
|
+
getStringFromJson(args.getString(0)),
|
|
67
|
+
args.getJSONArray(1),
|
|
68
|
+
args.getBoolean(2),
|
|
69
|
+
getStringFromJson(args.getString(3)),
|
|
70
|
+
args.getInt(4),
|
|
71
|
+
args.getInt(5),
|
|
72
|
+
getStringFromJson(args.getString(6)),
|
|
73
|
+
callbackContext
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
"close" -> close()
|
|
77
|
+
"addEventsListener" -> addEventsListener(callbackContext)
|
|
78
|
+
"removeEventsListener" -> removeEventsListener()
|
|
79
|
+
"getAnonymousUserId" -> getAnonymousUserId(callbackContext)
|
|
80
|
+
"userLogin" -> userLogin(getStringFromJson(args.getString(0)), callbackContext)
|
|
81
|
+
"userLogout" -> userLogout()
|
|
82
|
+
"setLanguage" -> setLanguage(getStringFromJson(args.getString(0)))
|
|
83
|
+
"setLogLevel" -> setLogLevel(args.getInt(0))
|
|
84
|
+
"setAttribute" -> setAttribute(args.getInt(0), getStringFromJson(args.getString(1)))
|
|
85
|
+
"setDefaultPresentationResultHandler" -> setDefaultPresentationResultHandler(
|
|
86
|
+
callbackContext
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
"purchasedSubscription" -> purchasedSubscription(callbackContext)
|
|
90
|
+
"readyToOpenDeeplink" -> readyToOpenDeeplink(args.getBoolean(0))
|
|
91
|
+
"synchronize" -> synchronize()
|
|
92
|
+
"presentPresentationWithIdentifier" -> presentPresentationWithIdentifier(
|
|
93
|
+
getStringFromJson(args.getString(0)),
|
|
94
|
+
getStringFromJson(args.getString(1)),
|
|
95
|
+
args.getBoolean(2),
|
|
96
|
+
callbackContext
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
"presentPresentationForPlacement" -> presentPresentationForPlacement(
|
|
100
|
+
getStringFromJson(args.getString(0)),
|
|
101
|
+
getStringFromJson(args.getString(1)),
|
|
102
|
+
args.getBoolean(2),
|
|
103
|
+
callbackContext
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
"presentProductWithIdentifier" -> presentProductWithIdentifier(
|
|
107
|
+
getStringFromJson(args.getString(0)),
|
|
108
|
+
getStringFromJson(args.getString(1)),
|
|
109
|
+
getStringFromJson(args.getString(2)),
|
|
110
|
+
args.getBoolean(3),
|
|
111
|
+
callbackContext
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
"presentPlanWithIdentifier" -> presentPlanWithIdentifier(
|
|
115
|
+
getStringFromJson(args.getString(0)),
|
|
116
|
+
getStringFromJson(args.getString(1)),
|
|
117
|
+
getStringFromJson(args.getString(2)),
|
|
118
|
+
args.getBoolean(3),
|
|
119
|
+
callbackContext
|
|
120
|
+
)
|
|
121
|
+
"fetchPresentation" -> fetchPresentation(
|
|
122
|
+
getStringFromJson(args.getString(0)),
|
|
123
|
+
getStringFromJson(args.getString(1)),
|
|
124
|
+
getStringFromJson(args.getString(2)),
|
|
125
|
+
callbackContext
|
|
126
|
+
)
|
|
127
|
+
"presentPresentation" -> presentPresentation(
|
|
128
|
+
args.getJSONObject(0),
|
|
129
|
+
args.getBoolean(1),
|
|
130
|
+
getStringFromJson(args.getString(2)),
|
|
131
|
+
callbackContext
|
|
132
|
+
)
|
|
133
|
+
"presentSubscriptions" -> presentSubscriptions()
|
|
134
|
+
"restoreAllProducts" -> restoreAllProducts(callbackContext)
|
|
135
|
+
"silentRestoreAllProducts" -> restoreAllProducts(callbackContext)
|
|
136
|
+
"userSubscriptions" -> userSubscriptions(callbackContext)
|
|
137
|
+
"isDeeplinkHandled" -> isDeeplinkHandled(
|
|
138
|
+
getStringFromJson(args.getString(0)),
|
|
139
|
+
callbackContext
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
"allProducts" -> allProducts(callbackContext)
|
|
143
|
+
"productWithIdentifier" -> productWithIdentifier(
|
|
144
|
+
getStringFromJson(args.getString(0)),
|
|
145
|
+
callbackContext
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
"planWithIdentifier" -> planWithIdentifier(
|
|
149
|
+
getStringFromJson(args.getString(0)),
|
|
150
|
+
callbackContext
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
"purchaseWithPlanVendorId" -> purchaseWithPlanVendorId(
|
|
154
|
+
getStringFromJson(args.getString(0)),
|
|
155
|
+
getStringFromJson(args.getString(1)),
|
|
156
|
+
getStringFromJson(args.getString(2)),
|
|
157
|
+
callbackContext
|
|
158
|
+
)
|
|
159
|
+
"setPaywallActionInterceptor" -> setPaywallActionInterceptor(callbackContext)
|
|
160
|
+
"onProcessAction" -> onProcessAction(args.getBoolean(0))
|
|
161
|
+
"closePresentation" -> closePresentation(callbackContext)
|
|
162
|
+
"hidePresentation" -> hidePresentation()
|
|
163
|
+
"showPresentation" -> showPresentation()
|
|
164
|
+
"userDidConsumeSubscriptionContent" -> userDidConsumeSubscriptionContent()
|
|
165
|
+
"setUserAttributeWithString" -> setUserAttributeWithString(getStringFromJson(args.getString(0)), getStringFromJson(args.getString(1)))
|
|
166
|
+
"setUserAttributeWithBoolean" -> setUserAttributeWithBoolean(getStringFromJson(args.getString(0)), args.getBoolean(1))
|
|
167
|
+
"setUserAttributeWithInt" -> setUserAttributeWithInt(getStringFromJson(args.getString(0)), args.getInt(1))
|
|
168
|
+
"setUserAttributeWithDouble" -> setUserAttributeWithDouble(getStringFromJson(args.getString(0)), args.getDouble(1))
|
|
169
|
+
"setUserAttributeWithDate" -> setUserAttributeWithDate(getStringFromJson(args.getString(0)), getStringFromJson(args.getString(1)))
|
|
170
|
+
"userAttribute" -> userAttribute(getStringFromJson(args.getString(0)), callbackContext)
|
|
171
|
+
"clearUserAttribute" -> clearUserAttribute(getStringFromJson(args.getString(0)))
|
|
172
|
+
"clearUserAttributes" -> clearUserAttributes()
|
|
173
|
+
"isEligibleForIntroOffer" -> isEligibleForIntroOffer(getStringFromJson(args.getString(0)), callbackContext)
|
|
174
|
+
"signPromotionalOffer" -> signPromotionalOffer(getStringFromJson(args.getString(0)), getStringFromJson(args.getString(1)), callbackContext)
|
|
175
|
+
else -> return false
|
|
176
|
+
}
|
|
177
|
+
} catch (e: JSONException) {
|
|
178
|
+
Log.e("Purchasely", String.format("Error executing action %s", action), e)
|
|
179
|
+
}
|
|
180
|
+
return true
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
private fun getStringFromJson(value: String?): String? {
|
|
184
|
+
return if (value == null || value == "null" || value.isEmpty()) {
|
|
185
|
+
null
|
|
186
|
+
} else value
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
private fun start(
|
|
190
|
+
apiKey: String?,
|
|
191
|
+
stores: JSONArray,
|
|
192
|
+
storeKit1: Boolean,
|
|
193
|
+
userId: String?,
|
|
194
|
+
logLevel: Int,
|
|
195
|
+
runningMode: Int,
|
|
196
|
+
cordovaSdkVersion: String?,
|
|
197
|
+
callbackContext: CallbackContext
|
|
198
|
+
) {
|
|
199
|
+
|
|
200
|
+
if(apiKey == null) {
|
|
201
|
+
callbackContext.error("API Key is null")
|
|
202
|
+
return
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
val list = ArrayList<String>()
|
|
206
|
+
for (i in 0 until stores.length()) {
|
|
207
|
+
try {
|
|
208
|
+
list.add(stores.getString(i))
|
|
209
|
+
} catch (e: JSONException) {
|
|
210
|
+
Log.e("Purchasely", "Error in store array" + e.message, e)
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
val storesInstances = getStoresInstances(list)
|
|
214
|
+
var plyRunningMode: PLYRunningMode = Full
|
|
215
|
+
if (runningMode == runningModePaywallObserver) plyRunningMode = PaywallObserver
|
|
216
|
+
Purchasely.Builder(cordova.context)
|
|
217
|
+
.apiKey(apiKey)
|
|
218
|
+
.stores(storesInstances)
|
|
219
|
+
.userId(userId)
|
|
220
|
+
.runningMode(plyRunningMode)
|
|
221
|
+
.logLevel(LogLevel.values()[logLevel])
|
|
222
|
+
.build()
|
|
223
|
+
Purchasely.sdkBridgeVersion = cordovaSdkVersion
|
|
224
|
+
Purchasely.appTechnology = PLYAppTechnology.CORDOVA
|
|
225
|
+
Purchasely.start { isConfigured: Boolean, error: PLYError? ->
|
|
226
|
+
if (isConfigured) {
|
|
227
|
+
callbackContext.success()
|
|
228
|
+
} else {
|
|
229
|
+
callbackContext.error(
|
|
230
|
+
if (error != null) error.message else "Purchasely SDK not configured"
|
|
231
|
+
)
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
private fun getStoresInstances(stores: List<String>): ArrayList<Store> {
|
|
237
|
+
val result = ArrayList<Store>()
|
|
238
|
+
if (stores.contains("Google") && Package.getPackage("io.purchasely.google") != null) {
|
|
239
|
+
try {
|
|
240
|
+
result.add(Class.forName("io.purchasely.google.GoogleStore").newInstance() as Store)
|
|
241
|
+
} catch (e: Exception) {
|
|
242
|
+
Log.e("Purchasely", "Google Store not found :" + e.message, e)
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
if (stores.contains("Huawei") && Package.getPackage("io.purchasely.huawei") != null) {
|
|
246
|
+
try {
|
|
247
|
+
result.add(Class.forName("io.purchasely.huawei.HuaweiStore").newInstance() as Store)
|
|
248
|
+
} catch (e: Exception) {
|
|
249
|
+
Log.e("Purchasely", "Huawei Store not found :" + e.message, e)
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
if (stores.contains("Amazon") && Package.getPackage("io.purchasely.amazon") != null) {
|
|
253
|
+
try {
|
|
254
|
+
result.add(Class.forName("io.purchasely.amazon.AmazonStore").newInstance() as Store)
|
|
255
|
+
} catch (e: Exception) {
|
|
256
|
+
Log.e("Purchasely", "Amazon Store not found :" + e.message, e)
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return result
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
private fun close() {
|
|
263
|
+
defaultCallback = null
|
|
264
|
+
purchaseCallback = null
|
|
265
|
+
paywallActionHandler = null
|
|
266
|
+
productActivity = null
|
|
267
|
+
Purchasely.close()
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
private fun addEventsListener(callbackContext: CallbackContext) {
|
|
271
|
+
eventsCallback = callbackContext
|
|
272
|
+
Purchasely.eventListener = object: EventListener {
|
|
273
|
+
override fun onEvent(event: PLYEvent) {
|
|
274
|
+
val map = HashMap<String?, Any?>()
|
|
275
|
+
map["name"] = event.name
|
|
276
|
+
map["properties"] = event.properties.toMap()
|
|
277
|
+
val pluginResult = PluginResult(PluginResult.Status.OK, JSONObject(map))
|
|
278
|
+
pluginResult.keepCallback = true
|
|
279
|
+
eventsCallback?.sendPluginResult(pluginResult)
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
private fun removeEventsListener() {
|
|
285
|
+
eventsCallback = null
|
|
286
|
+
Purchasely.eventListener = null
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
private fun getAnonymousUserId(callbackContext: CallbackContext) {
|
|
290
|
+
callbackContext.success(Purchasely.anonymousUserId)
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
private fun userLogin(userId: String?, callbackContext: CallbackContext) {
|
|
294
|
+
if(userId == null) {
|
|
295
|
+
callbackContext.sendPluginResult(PluginResult(PluginResult.Status.OK, false))
|
|
296
|
+
return
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
Purchasely.userLogin(userId) { refresh ->
|
|
300
|
+
callbackContext.sendPluginResult(PluginResult(PluginResult.Status.OK, refresh))
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
private fun userLogout() {
|
|
305
|
+
Purchasely.userLogout()
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
private fun setLogLevel(logLevel: Int) {
|
|
309
|
+
Purchasely.logLevel = LogLevel.values()[logLevel]
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
private fun setLanguage(language: String?) {
|
|
313
|
+
try {
|
|
314
|
+
Purchasely.language = Locale(language ?: "en")
|
|
315
|
+
} catch (e: Exception) {
|
|
316
|
+
Purchasely.language = Locale.getDefault()
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
private fun readyToOpenDeeplink(isReadyToPurchase: Boolean) {
|
|
321
|
+
Purchasely.readyToOpenDeeplink = isReadyToPurchase
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
private fun setAttribute(attribute: Int, value: String?) {
|
|
325
|
+
if(value == null) return
|
|
326
|
+
|
|
327
|
+
Purchasely.setAttribute(Attribute.values()[attribute], value)
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
private fun setDefaultPresentationResultHandler(callbackContext: CallbackContext) {
|
|
331
|
+
defaultCallback = callbackContext
|
|
332
|
+
Purchasely.setDefaultPresentationResultHandler { result: PLYProductViewResult, plan: PLYPlan? ->
|
|
333
|
+
sendPurchaseResult(
|
|
334
|
+
result,
|
|
335
|
+
plan
|
|
336
|
+
)
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
private fun purchasedSubscription(callbackContext: CallbackContext) {
|
|
341
|
+
Purchasely.purchaseListener = object : PurchaseListener {
|
|
342
|
+
override fun onPurchaseStateChanged(state: State) {
|
|
343
|
+
if (state is State.PurchaseComplete || state is State.RestorationComplete) {
|
|
344
|
+
val pluginResult = PluginResult(PluginResult.Status.OK, "")
|
|
345
|
+
pluginResult.keepCallback = true
|
|
346
|
+
callbackContext.sendPluginResult(pluginResult)
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
private fun synchronize() {
|
|
354
|
+
Purchasely.synchronize()
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
private fun userDidConsumeSubscriptionContent() {
|
|
358
|
+
Purchasely.userDidConsumeSubscriptionContent()
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
private fun presentPresentationWithIdentifier(
|
|
362
|
+
presentationVendorId: String?,
|
|
363
|
+
contentId: String?,
|
|
364
|
+
isFullScreen: Boolean,
|
|
365
|
+
callbackContext: CallbackContext
|
|
366
|
+
) {
|
|
367
|
+
purchaseCallback = callbackContext
|
|
368
|
+
val intent = PLYProductActivity.newIntent(cordova.activity)
|
|
369
|
+
intent.putExtra("presentationId", presentationVendorId)
|
|
370
|
+
intent.putExtra("contentId", contentId)
|
|
371
|
+
intent.putExtra("isFullScreen", isFullScreen)
|
|
372
|
+
cordova.activity.startActivity(intent)
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
private fun presentPresentationForPlacement(
|
|
376
|
+
placementVendorId: String?,
|
|
377
|
+
contentId: String?,
|
|
378
|
+
isFullScreen: Boolean,
|
|
379
|
+
callbackContext: CallbackContext
|
|
380
|
+
) {
|
|
381
|
+
purchaseCallback = callbackContext
|
|
382
|
+
val intent = PLYProductActivity.newIntent(cordova.activity)
|
|
383
|
+
intent.putExtra("placementId", placementVendorId)
|
|
384
|
+
intent.putExtra("contentId", contentId)
|
|
385
|
+
intent.putExtra("isFullScreen", isFullScreen)
|
|
386
|
+
cordova.activity.startActivity(intent)
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
private fun presentProductWithIdentifier(
|
|
390
|
+
productVendorId: String?,
|
|
391
|
+
presentationVendorId: String?,
|
|
392
|
+
contentId: String?,
|
|
393
|
+
isFullScreen: Boolean,
|
|
394
|
+
callbackContext: CallbackContext
|
|
395
|
+
) {
|
|
396
|
+
purchaseCallback = callbackContext
|
|
397
|
+
val intent = PLYProductActivity.newIntent(cordova.activity)
|
|
398
|
+
intent.putExtra("presentationId", presentationVendorId)
|
|
399
|
+
intent.putExtra("productId", productVendorId)
|
|
400
|
+
intent.putExtra("contentId", contentId)
|
|
401
|
+
intent.putExtra("isFullScreen", isFullScreen)
|
|
402
|
+
cordova.activity.startActivity(intent)
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
private fun presentPlanWithIdentifier(
|
|
406
|
+
planVendorId: String?,
|
|
407
|
+
presentationVendorId: String?,
|
|
408
|
+
contentId: String?,
|
|
409
|
+
isFullScreen: Boolean,
|
|
410
|
+
callbackContext: CallbackContext
|
|
411
|
+
) {
|
|
412
|
+
purchaseCallback = callbackContext
|
|
413
|
+
val intent = PLYProductActivity.newIntent(cordova.activity)
|
|
414
|
+
intent.putExtra("presentationId", presentationVendorId)
|
|
415
|
+
intent.putExtra("planId", planVendorId)
|
|
416
|
+
intent.putExtra("contentId", contentId)
|
|
417
|
+
intent.putExtra("isFullScreen", isFullScreen)
|
|
418
|
+
cordova.activity.startActivity(intent)
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
private fun fetchPresentation(
|
|
422
|
+
placementId: String?,
|
|
423
|
+
presentationId: String?,
|
|
424
|
+
contentId: String?,
|
|
425
|
+
callbackContext: CallbackContext) {
|
|
426
|
+
val properties = PLYPresentationViewProperties(
|
|
427
|
+
placementId = placementId,
|
|
428
|
+
presentationId = presentationId,
|
|
429
|
+
contentId = contentId)
|
|
430
|
+
|
|
431
|
+
Purchasely.fetchPresentation(properties = properties) { presentation: PLYPresentation?, error: PLYError? ->
|
|
432
|
+
if(presentation != null) {
|
|
433
|
+
presentationsLoaded.removeAll { it.id == presentation.id && it.placementId == presentation.placementId }
|
|
434
|
+
presentationsLoaded.add(presentation)
|
|
435
|
+
val map = presentation.toMap().mapValues {
|
|
436
|
+
val value = it.value
|
|
437
|
+
if(value is PLYPresentationType) value.ordinal
|
|
438
|
+
else value
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
val mutableMap = map.toMutableMap().apply {
|
|
442
|
+
//this["metadata"] = presentation.metadata?.toMap()
|
|
443
|
+
this["plans"] = (this["plans"] as List<PLYPresentationPlan>).map { it.toMap() }
|
|
444
|
+
}
|
|
445
|
+
callbackContext.success(JSONObject(map))
|
|
446
|
+
}
|
|
447
|
+
if(error != null) callbackContext.error(error.message ?: "Unable to fetch presentation")
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
// Delete when available in Android SDK
|
|
452
|
+
fun PLYPresentationPlan.toMap() : Map<String, String?> {
|
|
453
|
+
return mapOf(
|
|
454
|
+
Pair("planVendorId", planVendorId),
|
|
455
|
+
Pair("storeProductId", storeProductId),
|
|
456
|
+
Pair("basePlanId", basePlanId),
|
|
457
|
+
Pair("offerId", offerId)
|
|
458
|
+
)
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
private fun presentPresentation(presentationMap: JSONObject?,
|
|
462
|
+
isFullScreen: Boolean,
|
|
463
|
+
loadingBackgroundColor: String?,
|
|
464
|
+
callbackContext: CallbackContext) {
|
|
465
|
+
if (presentationMap == null) {
|
|
466
|
+
callbackContext.error("presentation cannot be null")
|
|
467
|
+
return
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
val presentation = presentationsLoaded.lastOrNull {
|
|
471
|
+
it.id == presentationMap.getString("id")
|
|
472
|
+
&& it.placementId == presentationMap.getString("placementId")
|
|
473
|
+
}
|
|
474
|
+
if(presentation == null) {
|
|
475
|
+
callbackContext.error("presentation cannot be found")
|
|
476
|
+
return
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
purchaseCallback = callbackContext
|
|
480
|
+
|
|
481
|
+
cordova.activity.let { activity ->
|
|
482
|
+
val intent = PLYProductActivity.newIntent(activity, PLYPresentationViewProperties(), isFullScreen, loadingBackgroundColor).apply {
|
|
483
|
+
putExtra("presentation", presentation)
|
|
484
|
+
}
|
|
485
|
+
activity.startActivity(intent)
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
private fun presentSubscriptions() {
|
|
491
|
+
val intent =
|
|
492
|
+
Intent(cordova.context, PLYSubscriptionsActivity::class.java)
|
|
493
|
+
cordova.activity.startActivity(intent)
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
private fun restoreAllProducts(callbackContext: CallbackContext) {
|
|
497
|
+
Purchasely.restoreAllProducts({ plyPlan: PLYPlan? ->
|
|
498
|
+
callbackContext.success(JSONObject(transformPlanToMap(plyPlan)))
|
|
499
|
+
}) { plyError: PLYError? ->
|
|
500
|
+
callbackContext.error(plyError?.message)
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
private fun userSubscriptions(callbackContext: CallbackContext) {
|
|
505
|
+
Purchasely.userSubscriptions(object : SubscriptionsListener {
|
|
506
|
+
override fun onSuccess(list: List<PLYSubscriptionData>) {
|
|
507
|
+
val result = JSONArray()
|
|
508
|
+
for (i in list.indices) {
|
|
509
|
+
val data = list[i]
|
|
510
|
+
val map = HashMap(data.toMap())
|
|
511
|
+
map["plan"] = transformPlanToMap(data.plan)
|
|
512
|
+
map["product"] = data.product.toMap()
|
|
513
|
+
if (data.data.storeType == StoreType.GOOGLE_PLAY_STORE) {
|
|
514
|
+
map["subscriptionSource"] = StoreType.GOOGLE_PLAY_STORE.ordinal
|
|
515
|
+
} else if (data.data.storeType == StoreType.AMAZON_APP_STORE) {
|
|
516
|
+
map["subscriptionSource"] = StoreType.AMAZON_APP_STORE.ordinal
|
|
517
|
+
} else if (data.data.storeType == StoreType.HUAWEI_APP_GALLERY) {
|
|
518
|
+
map["subscriptionSource"] = StoreType.HUAWEI_APP_GALLERY.ordinal
|
|
519
|
+
} else if (data.data.storeType == StoreType.APPLE_APP_STORE) {
|
|
520
|
+
map["subscriptionSource"] = StoreType.APPLE_APP_STORE.ordinal
|
|
521
|
+
}
|
|
522
|
+
result.put(JSONObject(map))
|
|
523
|
+
}
|
|
524
|
+
callbackContext.success(result)
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
override fun onFailure(throwable: Throwable) {
|
|
528
|
+
callbackContext.error(throwable.message)
|
|
529
|
+
}
|
|
530
|
+
})
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
private fun isDeeplinkHandled(deeplink: String?, callbackContext: CallbackContext) {
|
|
534
|
+
if (deeplink == null) {
|
|
535
|
+
callbackContext.error("Deeplink must not be null")
|
|
536
|
+
return
|
|
537
|
+
}
|
|
538
|
+
val uri = Uri.parse(deeplink)
|
|
539
|
+
callbackContext.sendPluginResult(
|
|
540
|
+
PluginResult(
|
|
541
|
+
PluginResult.Status.OK,
|
|
542
|
+
Purchasely.isDeeplinkHandled(uri)
|
|
543
|
+
)
|
|
544
|
+
)
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
private fun allProducts(callbackContext: CallbackContext) {
|
|
548
|
+
Purchasely.allProducts(object : ProductsListener {
|
|
549
|
+
override fun onSuccess(list: List<PLYProduct>) {
|
|
550
|
+
val result = JSONArray()
|
|
551
|
+
for (i in list.indices) {
|
|
552
|
+
result.put(JSONObject(list[i].toMap()))
|
|
553
|
+
}
|
|
554
|
+
callbackContext.success(result)
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
override fun onFailure(throwable: Throwable) {
|
|
558
|
+
callbackContext.error(throwable.message)
|
|
559
|
+
}
|
|
560
|
+
})
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
private fun productWithIdentifier(vendorId: String?, callbackContext: CallbackContext) {
|
|
564
|
+
if(vendorId == null) {
|
|
565
|
+
callbackContext.error("No product found with $vendorId")
|
|
566
|
+
return
|
|
567
|
+
}
|
|
568
|
+
Purchasely.product(vendorId, object : ProductListener {
|
|
569
|
+
override fun onSuccess(product: PLYProduct?) {
|
|
570
|
+
if (product != null) {
|
|
571
|
+
callbackContext.success(JSONObject(product.toMap()))
|
|
572
|
+
} else {
|
|
573
|
+
callbackContext.error("No product found with $vendorId")
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
override fun onFailure(throwable: Throwable) {
|
|
578
|
+
callbackContext.error(throwable.message)
|
|
579
|
+
}
|
|
580
|
+
})
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
private fun planWithIdentifier(vendorId: String?, callbackContext: CallbackContext) {
|
|
584
|
+
if(vendorId == null) {
|
|
585
|
+
callbackContext.error("No plan found with $vendorId")
|
|
586
|
+
return
|
|
587
|
+
}
|
|
588
|
+
Purchasely.plan(vendorId, object : PlanListener {
|
|
589
|
+
override fun onSuccess(plan: PLYPlan?) {
|
|
590
|
+
if (plan != null) {
|
|
591
|
+
callbackContext.success(JSONObject(transformPlanToMap(plan)))
|
|
592
|
+
} else {
|
|
593
|
+
callbackContext.error("No plan found with $vendorId")
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
override fun onFailure(throwable: Throwable) {
|
|
598
|
+
callbackContext.error(throwable.message)
|
|
599
|
+
}
|
|
600
|
+
})
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
private fun purchaseWithPlanVendorId(
|
|
604
|
+
planVendorId: String?,
|
|
605
|
+
offerId: String?,
|
|
606
|
+
contentId: String?,
|
|
607
|
+
callbackContext: CallbackContext
|
|
608
|
+
) {
|
|
609
|
+
if(planVendorId == null) {
|
|
610
|
+
callbackContext.error("No plan found with $planVendorId")
|
|
611
|
+
return
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
Purchasely.plan(planVendorId, object : PlanListener {
|
|
615
|
+
override fun onSuccess(plyPlan: PLYPlan?) {
|
|
616
|
+
if (plyPlan != null) {
|
|
617
|
+
val offer = plyPlan.promoOffers.firstOrNull { it.vendorId == offerId }
|
|
618
|
+
Purchasely.purchase(cordova.activity, plyPlan, offer, contentId,
|
|
619
|
+
{ plyPlan1: PLYPlan? ->
|
|
620
|
+
callbackContext.success(JSONObject(transformPlanToMap(plyPlan1)))
|
|
621
|
+
}) { plyError: PLYError? ->
|
|
622
|
+
callbackContext.error(plyError?.message)
|
|
623
|
+
}
|
|
624
|
+
} else {
|
|
625
|
+
callbackContext.error("No plan found with $planVendorId")
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
override fun onFailure(throwable: Throwable) {
|
|
630
|
+
callbackContext.error(throwable.message)
|
|
631
|
+
}
|
|
632
|
+
})
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
private fun setPaywallActionInterceptor(callbackContext: CallbackContext) {
|
|
636
|
+
Purchasely.setPaywallActionsInterceptor { info, action, parameters, processAction ->
|
|
637
|
+
paywallActionHandler = processAction
|
|
638
|
+
paywallAction = action
|
|
639
|
+
|
|
640
|
+
interceptorActivity = WeakReference(info?.activity)
|
|
641
|
+
|
|
642
|
+
val parametersForCordova = hashMapOf<String, Any?>();
|
|
643
|
+
parametersForCordova["title"] = parameters.title
|
|
644
|
+
parametersForCordova["url"] = parameters.url?.toString()
|
|
645
|
+
parametersForCordova["plan"] = transformPlanToMap(parameters.plan)
|
|
646
|
+
parametersForCordova["offer"] = mapOf(
|
|
647
|
+
"vendorId" to parameters.offer?.vendorId,
|
|
648
|
+
"storeOfferId" to parameters.offer?.storeOfferId
|
|
649
|
+
)
|
|
650
|
+
parametersForCordova["subscriptionOffer"] = parameters.subscriptionOffer?.toMap()
|
|
651
|
+
parametersForCordova["presentation"] = parameters.presentation
|
|
652
|
+
parametersForCordova["placement"] = parameters.placement
|
|
653
|
+
|
|
654
|
+
val result = PluginResult(
|
|
655
|
+
PluginResult.Status.OK,
|
|
656
|
+
JSONObject(
|
|
657
|
+
hashMapOf<String, Any?>(
|
|
658
|
+
Pair("info", mapOf(
|
|
659
|
+
Pair("contentId", info?.contentId),
|
|
660
|
+
Pair("presentationId", info?.presentationId),
|
|
661
|
+
Pair("placementId", info?.placementId),
|
|
662
|
+
Pair("abTestId", info?.abTestId),
|
|
663
|
+
Pair("abTestVariantId", info?.abTestVariantId)
|
|
664
|
+
)),
|
|
665
|
+
Pair("action", action.value),
|
|
666
|
+
Pair("parameters", parametersForCordova.filterNot { it.value == null })
|
|
667
|
+
)
|
|
668
|
+
)
|
|
669
|
+
)
|
|
670
|
+
result.keepCallback = true
|
|
671
|
+
callbackContext.sendPluginResult(result)
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
private fun closePresentation(callbackContext: CallbackContext) {
|
|
676
|
+
val openedPaywall = productActivity?.activity?.get()
|
|
677
|
+
openedPaywall?.finish()
|
|
678
|
+
productActivity = null
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
private fun onProcessAction(processAction: Boolean) {
|
|
682
|
+
val activityHandler = interceptorActivity?.get() ?: productActivity?.activity?.get() ?: cordova.activity
|
|
683
|
+
activityHandler?.runOnUiThread {
|
|
684
|
+
paywallActionHandler?.invoke(processAction)
|
|
685
|
+
|
|
686
|
+
interceptorActivity?.clear()
|
|
687
|
+
interceptorActivity = null
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
private fun showPresentation() {
|
|
692
|
+
val currentActivity = interceptorActivity?.get()
|
|
693
|
+
|
|
694
|
+
if (currentActivity != null && !currentActivity.isFinishing && !currentActivity.isDestroyed) {
|
|
695
|
+
cordova.activity?.let {
|
|
696
|
+
it.startActivity(
|
|
697
|
+
Intent(it, currentActivity::class.java).apply {
|
|
698
|
+
//flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
|
699
|
+
flags = Intent.FLAG_ACTIVITY_REORDER_TO_FRONT
|
|
700
|
+
}
|
|
701
|
+
)
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
else {
|
|
705
|
+
productActivity?.relaunch(cordova)
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
private fun hidePresentation() {
|
|
710
|
+
val cordovaActivity = cordova.activity
|
|
711
|
+
val activity = productActivity?.activity?.get() ?: cordovaActivity
|
|
712
|
+
cordovaActivity?.startActivity(
|
|
713
|
+
Intent(activity, cordovaActivity::class.java).apply {
|
|
714
|
+
flags = Intent.FLAG_ACTIVITY_REORDER_TO_FRONT
|
|
715
|
+
}
|
|
716
|
+
)
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
fun setUserAttributeWithString(key: String?, value: String?) {
|
|
720
|
+
if(key == null || value == null) return
|
|
721
|
+
Purchasely.setUserAttribute(key, value)
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
fun setUserAttributeWithInt(key: String?, value: Int?) {
|
|
725
|
+
if(key == null || value == null) return
|
|
726
|
+
Purchasely.setUserAttribute(key, value)
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
fun setUserAttributeWithDouble(key: String?, value: Double?) {
|
|
730
|
+
if(key == null || value == null) return
|
|
731
|
+
Purchasely.setUserAttribute(key, value.toFloat())
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
fun setUserAttributeWithBoolean(key: String?, value: Boolean?) {
|
|
735
|
+
if(key == null || value == null) return
|
|
736
|
+
Purchasely.setUserAttribute(key, value)
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
fun setUserAttributeWithDate(key: String?, value: String?) {
|
|
740
|
+
if(key == null || value == null) return
|
|
741
|
+
val format = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
|
742
|
+
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX", Locale.getDefault())
|
|
743
|
+
} else {
|
|
744
|
+
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault())
|
|
745
|
+
}
|
|
746
|
+
format.timeZone = TimeZone.getTimeZone("GMT")
|
|
747
|
+
val calendar = Calendar.getInstance()
|
|
748
|
+
try {
|
|
749
|
+
format.parse(value)?.let {
|
|
750
|
+
calendar.time = it
|
|
751
|
+
}
|
|
752
|
+
Purchasely.setUserAttribute(key, calendar.time)
|
|
753
|
+
} catch (e: Exception) {
|
|
754
|
+
Log.e("Purchasely", "Cannot save date attribute $key", e)
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
fun userAttribute(key: String?, callbackContext: CallbackContext) {
|
|
759
|
+
if(key == null) return
|
|
760
|
+
val result = getUserAttributeValueForCordova(Purchasely.userAttribute(key))
|
|
761
|
+
if(result != null) {
|
|
762
|
+
callbackContext.success(getUserAttributeValueForCordova(result))
|
|
763
|
+
} else {
|
|
764
|
+
callbackContext.error("No user attribute found with $key")
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
private fun getUserAttributeValueForCordova(value: Any?): String? {
|
|
769
|
+
return when (value) {
|
|
770
|
+
is Date -> {
|
|
771
|
+
val format = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
|
772
|
+
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX", Locale.getDefault())
|
|
773
|
+
} else {
|
|
774
|
+
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault())
|
|
775
|
+
}
|
|
776
|
+
format.timeZone = TimeZone.getTimeZone("GMT")
|
|
777
|
+
try {
|
|
778
|
+
format.format(value)
|
|
779
|
+
} catch (e: Exception) {
|
|
780
|
+
""
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
is Int -> value.toString()
|
|
784
|
+
//awful but to keep same precision so 1.2f = 1.2 double and not 1.20000056
|
|
785
|
+
is Float -> value.toString().toDouble().toString()
|
|
786
|
+
is String -> value
|
|
787
|
+
is Boolean -> value.toString()
|
|
788
|
+
else -> null
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
fun clearUserAttribute(key: String?) {
|
|
793
|
+
if(key == null) return
|
|
794
|
+
Purchasely.clearUserAttribute(key)
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
fun clearUserAttributes() {
|
|
798
|
+
Purchasely.clearUserAttributes()
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
private fun isEligibleForIntroOffer(planId: String?, callbackContext: CallbackContext) {
|
|
802
|
+
Purchasely.plan(planId,
|
|
803
|
+
onSuccess = { plan ->
|
|
804
|
+
callbackContext.sendPluginResult(PluginResult(PluginResult.Status.OK, plan?.isEligibleToIntroOffer(null) ?: false))
|
|
805
|
+
},
|
|
806
|
+
onError = { error ->
|
|
807
|
+
callbackContext.error(error.message ?: "Unable to fetch plan")
|
|
808
|
+
}
|
|
809
|
+
)
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
private fun signPromotionalOffer(storeProductId: String?, storeOfferId: String?, callbackContext: CallbackContext) {
|
|
813
|
+
callbackContext.error("No signing required on Android")
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
|
|
817
|
+
class ProductActivity {
|
|
818
|
+
var presentationId: String? = null
|
|
819
|
+
var placementId: String? = null
|
|
820
|
+
var productId: String? = null
|
|
821
|
+
var planId: String? = null
|
|
822
|
+
var contentId: String? = null
|
|
823
|
+
var presentation: PLYPresentation? = null
|
|
824
|
+
var isFullScreen = false
|
|
825
|
+
var loadingBackgroundColor: String? = null
|
|
826
|
+
var activity: WeakReference<PLYProductActivity>? = null
|
|
827
|
+
fun relaunch(cordova: CordovaInterface): Boolean {
|
|
828
|
+
var backgroundActivity: PLYProductActivity? = null
|
|
829
|
+
if (activity != null) {
|
|
830
|
+
backgroundActivity = activity?.get()
|
|
831
|
+
}
|
|
832
|
+
return if (backgroundActivity != null && !backgroundActivity.isFinishing
|
|
833
|
+
&& !backgroundActivity.isDestroyed
|
|
834
|
+
) {
|
|
835
|
+
val intent = Intent(cordova.activity, PLYProductActivity::class.java)
|
|
836
|
+
intent.putExtra("presentation", presentation)
|
|
837
|
+
intent.putExtra("presentationId", presentationId)
|
|
838
|
+
intent.putExtra("placementId", placementId)
|
|
839
|
+
intent.putExtra("productId", productId)
|
|
840
|
+
intent.putExtra("planId", planId)
|
|
841
|
+
intent.putExtra("contentId", contentId)
|
|
842
|
+
intent.putExtra("isFullScreen", isFullScreen)
|
|
843
|
+
intent.putExtra("background_color", loadingBackgroundColor)
|
|
844
|
+
intent.flags = Intent.FLAG_ACTIVITY_REORDER_TO_FRONT
|
|
845
|
+
cordova.activity.startActivity(intent)
|
|
846
|
+
true
|
|
847
|
+
} else {
|
|
848
|
+
val intent = PLYProductActivity.newIntent(cordova.activity)
|
|
849
|
+
intent.putExtra("presentation", presentation)
|
|
850
|
+
intent.putExtra("presentationId", presentationId)
|
|
851
|
+
intent.putExtra("placementId", placementId)
|
|
852
|
+
intent.putExtra("productId", productId)
|
|
853
|
+
intent.putExtra("planId", planId)
|
|
854
|
+
intent.putExtra("contentId", contentId)
|
|
855
|
+
intent.putExtra("isFullScreen", isFullScreen)
|
|
856
|
+
intent.putExtra("background_color", loadingBackgroundColor)
|
|
857
|
+
cordova.activity.startActivity(intent)
|
|
858
|
+
false
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
companion object {
|
|
864
|
+
var defaultCallback: CallbackContext? = null
|
|
865
|
+
var purchaseCallback: CallbackContext? = null
|
|
866
|
+
var eventsCallback: CallbackContext? = null
|
|
867
|
+
var productActivity: ProductActivity? = null
|
|
868
|
+
|
|
869
|
+
var interceptorActivity: WeakReference<Activity>? = null
|
|
870
|
+
|
|
871
|
+
val presentationsLoaded = mutableListOf<PLYPresentation>()
|
|
872
|
+
|
|
873
|
+
private const val runningModePaywallObserver = 2
|
|
874
|
+
private const val runningModeFull = 3
|
|
875
|
+
|
|
876
|
+
fun sendPurchaseResult(result: PLYProductViewResult, plan: PLYPlan?) {
|
|
877
|
+
var productViewResult = 0
|
|
878
|
+
if (result == PLYProductViewResult.PURCHASED) {
|
|
879
|
+
productViewResult = PLYProductViewResult.PURCHASED.ordinal
|
|
880
|
+
} else if (result == PLYProductViewResult.CANCELLED) {
|
|
881
|
+
productViewResult = PLYProductViewResult.CANCELLED.ordinal
|
|
882
|
+
} else if (result == PLYProductViewResult.RESTORED) {
|
|
883
|
+
productViewResult = PLYProductViewResult.RESTORED.ordinal
|
|
884
|
+
}
|
|
885
|
+
val map = HashMap<String?, Any?>()
|
|
886
|
+
map["result"] = productViewResult
|
|
887
|
+
map["plan"] = transformPlanToMap(plan)
|
|
888
|
+
if (purchaseCallback != null) {
|
|
889
|
+
purchaseCallback?.success(JSONObject(map))
|
|
890
|
+
purchaseCallback = null
|
|
891
|
+
} else if (defaultCallback != null) {
|
|
892
|
+
val pluginResult = PluginResult(PluginResult.Status.OK, JSONObject(map))
|
|
893
|
+
pluginResult.keepCallback = true
|
|
894
|
+
defaultCallback?.sendPluginResult(pluginResult)
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
private fun transformPlanToMap(plan: PLYPlan?): Map<String?, Any?> {
|
|
899
|
+
if (plan == null) return HashMap()
|
|
900
|
+
val map = HashMap(plan.toMap())
|
|
901
|
+
if (plan.type == DistributionType.CONSUMABLE) {
|
|
902
|
+
map["type"] = DistributionType.CONSUMABLE.ordinal
|
|
903
|
+
} else if (plan.type == DistributionType.CONSUMABLE) {
|
|
904
|
+
map["type"] = DistributionType.NON_CONSUMABLE.ordinal
|
|
905
|
+
} else if (plan.type == DistributionType.NON_CONSUMABLE) {
|
|
906
|
+
map["type"] = DistributionType.RENEWING_SUBSCRIPTION.ordinal
|
|
907
|
+
} else if (plan.type == DistributionType.NON_RENEWING_SUBSCRIPTION) {
|
|
908
|
+
map["type"] = DistributionType.NON_RENEWING_SUBSCRIPTION.ordinal
|
|
909
|
+
} else if (plan.type == DistributionType.UNKNOWN) {
|
|
910
|
+
map["type"] = DistributionType.UNKNOWN.ordinal
|
|
911
|
+
}
|
|
912
|
+
map["isEligibleForIntroOffer"] = plan.isEligibleToIntroOffer(null)
|
|
913
|
+
return map
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
}
|