@kontextso/sdk-react-native 3.2.2-rc.0 → 3.3.0-rc.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/android/src/main/java/so/kontext/react/RNKontextModuleImpl.kt +36 -0
- package/android/src/newarch/java/so/kontext/react/RNKontextModule.kt +4 -0
- package/android/src/oldarch/java/so/kontext/react/RNKontextModule.kt +5 -0
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/ios/KontextSDK.swift +50 -0
- package/ios/RNKontext.mm +12 -0
- package/package.json +2 -2
- package/src/NativeRNKontext.ts +1 -0
|
@@ -3,7 +3,9 @@ package so.kontext.react
|
|
|
3
3
|
import com.facebook.react.bridge.Promise
|
|
4
4
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
5
5
|
import android.content.Context
|
|
6
|
+
import android.content.SharedPreferences
|
|
6
7
|
import android.media.AudioManager
|
|
8
|
+
import android.preference.PreferenceManager
|
|
7
9
|
|
|
8
10
|
class RNKontextModuleImpl(private val reactContext: ReactApplicationContext) {
|
|
9
11
|
fun isSoundOn(promise: Promise?) {
|
|
@@ -15,6 +17,40 @@ class RNKontextModuleImpl(private val reactContext: ReactApplicationContext) {
|
|
|
15
17
|
promise?.resolve(volume > MINIMAL_VOLUME_THRESHOLD)
|
|
16
18
|
}
|
|
17
19
|
|
|
20
|
+
fun getTcfData(promise: Promise) {
|
|
21
|
+
try {
|
|
22
|
+
val prefs = PreferenceManager.getDefaultSharedPreferences(reactContext.applicationContext)
|
|
23
|
+
val all = prefs.all
|
|
24
|
+
|
|
25
|
+
val out = HashMap<String, Any?>(32)
|
|
26
|
+
|
|
27
|
+
for ((key, value) in all) {
|
|
28
|
+
if (!key.startsWith("IABTCF_")) continue
|
|
29
|
+
out[key] = normalizeForReactNative(value)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Promise.resolve accepts Map<String, Any?> and RN will bridge it to JS object
|
|
33
|
+
promise.resolve(out)
|
|
34
|
+
} catch (t: Throwable) {
|
|
35
|
+
promise.reject("TCF_ERROR", "Failed to read IABTCF_* from SharedPreferences", t)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
private fun normalizeForReactNative(value: Any?): Any? {
|
|
40
|
+
return when (value) {
|
|
41
|
+
null -> null
|
|
42
|
+
is String -> value
|
|
43
|
+
is Boolean -> value
|
|
44
|
+
is Int -> value
|
|
45
|
+
is Long -> value
|
|
46
|
+
is Float -> value
|
|
47
|
+
is Double -> value
|
|
48
|
+
is Number -> value
|
|
49
|
+
else -> value.toString() // extremely rare, but avoids crashing bridge
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
|
|
18
54
|
companion object {
|
|
19
55
|
private const val MINIMAL_VOLUME_THRESHOLD = 0.0f
|
|
20
56
|
}
|
|
@@ -16,6 +16,10 @@ class RNKontextModule(reactContext: ReactApplicationContext) :
|
|
|
16
16
|
impl.isSoundOn(promise)
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
override fun getTcfData(promise: Promise) {
|
|
20
|
+
impl.getTcfData(promise)
|
|
21
|
+
}
|
|
22
|
+
|
|
19
23
|
// ---------- iOS-only: SKOverlay ----------
|
|
20
24
|
override fun presentSKOverlay(appStoreId: String, position: String, dismissible: Boolean, promise: Promise?) {
|
|
21
25
|
promise?.resolve(false)
|
package/dist/index.js
CHANGED
|
@@ -662,7 +662,7 @@ var import_react_native5 = require("react-native");
|
|
|
662
662
|
var import_react_native_device_info = __toESM(require("react-native-device-info"));
|
|
663
663
|
|
|
664
664
|
// package.json
|
|
665
|
-
var version = "3.2.2
|
|
665
|
+
var version = "3.2.2";
|
|
666
666
|
|
|
667
667
|
// src/context/AdsProvider.tsx
|
|
668
668
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
package/dist/index.mjs
CHANGED
|
@@ -634,7 +634,7 @@ import { Appearance, Dimensions, PixelRatio, Platform as Platform3 } from "react
|
|
|
634
634
|
import DeviceInfo from "react-native-device-info";
|
|
635
635
|
|
|
636
636
|
// package.json
|
|
637
|
-
var version = "3.2.2
|
|
637
|
+
var version = "3.2.2";
|
|
638
638
|
|
|
639
639
|
// src/context/AdsProvider.tsx
|
|
640
640
|
import { jsx as jsx4 } from "react/jsx-runtime";
|
package/ios/KontextSDK.swift
CHANGED
|
@@ -97,4 +97,54 @@ public class KontextSDK: NSObject {
|
|
|
97
97
|
resolve(ok)
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
|
+
|
|
101
|
+
// MARK: - TCF (IABTCF_*)
|
|
102
|
+
|
|
103
|
+
/// Returns all `IABTCF_*` values from `UserDefaults`.
|
|
104
|
+
/// Values are normalized to React Native bridge-safe types:
|
|
105
|
+
/// - String / NSNumber / NSNull
|
|
106
|
+
/// - (rare) Data is returned as base64 String
|
|
107
|
+
@objc
|
|
108
|
+
public static func getTcfData() -> NSDictionary {
|
|
109
|
+
let all = UserDefaults.standard.dictionaryRepresentation
|
|
110
|
+
|
|
111
|
+
let out = NSMutableDictionary()
|
|
112
|
+
out.reserveCapacity(32)
|
|
113
|
+
|
|
114
|
+
for (key, value) in all where key.hasPrefix("IABTCF_") {
|
|
115
|
+
if let normalized = normalizeForReactNative(value) {
|
|
116
|
+
out[key] = normalized
|
|
117
|
+
} else {
|
|
118
|
+
out[key] = NSNull()
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return out
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
private static func normalizeForReactNative(_ value: Any) -> Any? {
|
|
126
|
+
switch value {
|
|
127
|
+
case is NSNull:
|
|
128
|
+
return NSNull()
|
|
129
|
+
|
|
130
|
+
case let s as String:
|
|
131
|
+
return s
|
|
132
|
+
|
|
133
|
+
case let n as NSNumber:
|
|
134
|
+
// NSNumber covers Int/Double/Bool in ObjC bridging.
|
|
135
|
+
return n
|
|
136
|
+
|
|
137
|
+
case let b as Bool:
|
|
138
|
+
// Just in case; usually arrives as NSNumber already.
|
|
139
|
+
return NSNumber(value: b)
|
|
140
|
+
|
|
141
|
+
case let d as Data:
|
|
142
|
+
// Uncommon for TCF keys, but safe fallback.
|
|
143
|
+
return d.base64EncodedString()
|
|
144
|
+
|
|
145
|
+
default:
|
|
146
|
+
return nil
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
100
150
|
}
|
package/ios/RNKontext.mm
CHANGED
|
@@ -50,6 +50,12 @@ RCT_EXPORT_MODULE()
|
|
|
50
50
|
return std::make_shared<facebook::react::NativeRNKontextSpecJSI>(params);
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
- (void)getTcfData:(RCTPromiseResolveBlock)resolve
|
|
54
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
55
|
+
{
|
|
56
|
+
resolve([KontextSDK getTcfData]);
|
|
57
|
+
}
|
|
58
|
+
|
|
53
59
|
#else
|
|
54
60
|
|
|
55
61
|
RCT_EXPORT_METHOD(isSoundOn : (RCTPromiseResolveBlock)resolve
|
|
@@ -91,6 +97,12 @@ RCT_EXPORT_METHOD(dismissSKStoreProduct:(RCTPromiseResolveBlock)resolve
|
|
|
91
97
|
[KontextSDK dismissSKStoreProduct:resolve rejecter:reject];
|
|
92
98
|
}
|
|
93
99
|
|
|
100
|
+
RCT_EXPORT_METHOD(getTcfData:(RCTPromiseResolveBlock)resolve
|
|
101
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
102
|
+
{
|
|
103
|
+
resolve([KontextSDK getTcfData]);
|
|
104
|
+
}
|
|
105
|
+
|
|
94
106
|
#endif
|
|
95
107
|
|
|
96
108
|
@end
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kontextso/sdk-react-native",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.0-rc.0",
|
|
4
4
|
"description": "Kontext SDK for React Native",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"react-native-webview": "^13.10.0"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@kontextso/sdk-react": "^3.0.
|
|
57
|
+
"@kontextso/sdk-react": "^3.0.6"
|
|
58
58
|
},
|
|
59
59
|
"files": [
|
|
60
60
|
"dist/*",
|
package/src/NativeRNKontext.ts
CHANGED
|
@@ -7,6 +7,7 @@ export interface Spec extends TurboModule {
|
|
|
7
7
|
dismissSKOverlay(): Promise<boolean>
|
|
8
8
|
presentSKStoreProduct(appStoreId: string): Promise<boolean>
|
|
9
9
|
dismissSKStoreProduct(): Promise<boolean>
|
|
10
|
+
getTcfData(): Promise<Record<string, string | number | boolean | null>>
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
export default TurboModuleRegistry.getEnforcing<Spec>('RNKontext')
|