react-native-quicktracking-analytics-module 2.0.2 → 2.1.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.
Files changed (48) hide show
  1. package/LICENSE +1 -1
  2. package/QuicktrackingAnalyticsModule.podspec +29 -0
  3. package/README.md +210 -151
  4. package/android/build.gradle +40 -101
  5. package/android/gradle.properties +5 -5
  6. package/android/src/main/AndroidManifest.xml +1 -2
  7. package/android/src/main/AndroidManifestNew.xml +2 -0
  8. package/android/src/main/java/com/quicktrackinganalyticsmodule/QTSDKManager.kt +112 -0
  9. package/android/src/main/java/com/quicktrackinganalyticsmodule/QuicktrackingAnalyticsModuleModule.kt +259 -0
  10. package/android/src/main/java/com/quicktrackinganalyticsmodule/QuicktrackingAnalyticsModulePackage.kt +17 -0
  11. package/android/src/main/java/com/quicktrackinganalyticsmodule/property/QTViewProperties.kt +84 -0
  12. package/android/src/main/java/com/quicktrackinganalyticsmodule/utils/QTLog.kt +119 -0
  13. package/android/src/main/java/com/quicktrackinganalyticsmodule/utils/RNPropertyManager.kt +35 -0
  14. package/android/src/main/java/com/quicktrackinganalyticsmodule/utils/RNTouchTargetHelper.kt +162 -0
  15. package/android/src/main/java/com/quicktrackinganalyticsmodule/utils/RNUtils.kt +170 -0
  16. package/android/src/main/java/com/quicktrackinganalyticsmodule/utils/RNViewUtils.kt +233 -0
  17. package/ios/QuicktrackingAnalyticsModule.h +1 -4
  18. package/ios/{QuicktrackingAnalyticsModule.m → QuicktrackingAnalyticsModule.mm} +144 -110
  19. package/lib/commonjs/hook.js +564 -0
  20. package/lib/commonjs/hook.js.map +1 -0
  21. package/lib/commonjs/index.js +276 -166
  22. package/lib/commonjs/index.js.map +1 -0
  23. package/lib/commonjs/package.json +1 -0
  24. package/lib/module/hook.js +564 -0
  25. package/lib/module/hook.js.map +1 -0
  26. package/lib/module/index.js +253 -164
  27. package/lib/module/index.js.map +1 -0
  28. package/lib/typescript/index.d.ts +120 -79
  29. package/lib/typescript/index.d.ts.map +1 -0
  30. package/package.json +83 -67
  31. package/src/hook.js +3 -3
  32. package/src/index.tsx +266 -169
  33. package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  34. package/android/gradle/wrapper/gradle-wrapper.properties +0 -5
  35. package/android/gradlew +0 -234
  36. package/android/gradlew.bat +0 -89
  37. package/android/src/main/java/com/reactnativequicktrackinganalyticsmodule/QTSDKManager.java +0 -93
  38. package/android/src/main/java/com/reactnativequicktrackinganalyticsmodule/QuicktrackingAnalyticsModule.java +0 -242
  39. package/android/src/main/java/com/reactnativequicktrackinganalyticsmodule/QuicktrackingAnalyticsModulePackage.java +0 -28
  40. package/android/src/main/java/com/reactnativequicktrackinganalyticsmodule/property/QTViewProperties.java +0 -48
  41. package/android/src/main/java/com/reactnativequicktrackinganalyticsmodule/utils/QTLog.java +0 -122
  42. package/android/src/main/java/com/reactnativequicktrackinganalyticsmodule/utils/RNPropertyManager.java +0 -29
  43. package/android/src/main/java/com/reactnativequicktrackinganalyticsmodule/utils/RNTouchTargetHelper.java +0 -139
  44. package/android/src/main/java/com/reactnativequicktrackinganalyticsmodule/utils/RNUtils.java +0 -188
  45. package/android/src/main/java/com/reactnativequicktrackinganalyticsmodule/utils/RNViewUtils.java +0 -148
  46. package/ios/QuicktrackingAnalyticsModule.xcodeproj/project.pbxproj +0 -282
  47. package/ios/QuicktrackingAnalyticsModule.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
  48. package/react-native-quicktracking-analytics-module.podspec +0 -37
@@ -0,0 +1,119 @@
1
+ package com.quicktrackinganalyticsmodule.utils
2
+
3
+ import android.util.Log
4
+
5
+ object QTLog {
6
+ private var debug = false
7
+ private var enableLog = false
8
+ private var disableSDK = false
9
+ private const val CHUNK_SIZE = 4000
10
+
11
+ fun d(tag: String, msg: String) {
12
+ if (debug && !disableSDK) {
13
+ info(tag, msg, null)
14
+ }
15
+ }
16
+
17
+ fun t(msg: String, vararg args: Any) {
18
+ if (enableLog && !disableSDK) {
19
+ i("===TEST===", msg, *args)
20
+ }
21
+ }
22
+
23
+ fun d(tag: String, msg: String, tr: Throwable?) {
24
+ if (debug && !disableSDK) {
25
+ info(tag, msg, tr)
26
+ }
27
+ }
28
+
29
+ fun i(tag: String, msg: String) {
30
+ if (enableLog && !disableSDK) {
31
+ info(tag, msg, null)
32
+ }
33
+ }
34
+
35
+ fun i(tag: String, tr: Throwable) {
36
+ if (enableLog && !disableSDK) {
37
+ info(tag, "", tr)
38
+ }
39
+ }
40
+
41
+ fun i(tag: String, msg: String, tr: Throwable?) {
42
+ if (enableLog && !disableSDK) {
43
+ info(tag, msg, tr)
44
+ }
45
+ }
46
+
47
+ fun i(tag: String, msg: String, vararg args: Any) {
48
+ if (enableLog && !disableSDK) {
49
+ info(tag, String.format(msg, *args), null)
50
+ }
51
+ }
52
+
53
+ private fun info(tag: String, msg: String?, tr: Throwable?) {
54
+ try {
55
+ if (msg != null && msg.isNotEmpty()) {
56
+ val bytes = msg.toByteArray()
57
+ val length = bytes.size
58
+ if (length <= CHUNK_SIZE) {
59
+ Log.i(tag, msg, tr)
60
+ } else {
61
+ var index = 0
62
+ var lastIndexOfLF = 0
63
+ //当最后一次剩余值小于 CHUNK_SIZE 时,不需要再截断
64
+ while (index < length - CHUNK_SIZE) {
65
+ lastIndexOfLF = lastIndexOfLF(bytes, index)
66
+ val chunkLength = lastIndexOfLF - index
67
+ Log.i(tag, String(bytes, index, chunkLength), null)
68
+ index = if (chunkLength < CHUNK_SIZE) {
69
+ //跳过换行符
70
+ lastIndexOfLF + 1
71
+ } else {
72
+ lastIndexOfLF
73
+ }
74
+ }
75
+ if (length > index) {
76
+ Log.i(tag, String(bytes, index, length - index), tr)
77
+ }
78
+ }
79
+ } else {
80
+ Log.i(tag, null, tr)
81
+ }
82
+ } catch (e: Exception) {
83
+ printStackTrace(e)
84
+ }
85
+ }
86
+
87
+ private fun lastIndexOfLF(bytes: ByteArray, fromIndex: Int): Int {
88
+ val index = minOf(fromIndex + CHUNK_SIZE, bytes.size - 1)
89
+ for (i in index downTo index - CHUNK_SIZE) {
90
+ //返回换行符的位置
91
+ if (bytes[i] == 10.toByte()) {
92
+ return i
93
+ }
94
+ }
95
+ return index
96
+ }
97
+
98
+ fun printStackTrace(e: Exception) {
99
+ if (enableLog && !disableSDK) {
100
+ Log.e("QuickTracking Exception", "", e)
101
+ }
102
+ }
103
+
104
+ fun setDebug(isDebug: Boolean) {
105
+ debug = isDebug
106
+ }
107
+
108
+ fun setEnableLog(isEnableLog: Boolean) {
109
+ enableLog = isEnableLog
110
+ }
111
+
112
+ fun setDisableSDK(configDisableSDK: Boolean) {
113
+ disableSDK = configDisableSDK
114
+ }
115
+
116
+ fun isLogEnabled(): Boolean = enableLog
117
+
118
+ fun isDebug(): Boolean = debug
119
+ }
@@ -0,0 +1,35 @@
1
+ package com.quicktrackinganalyticsmodule.utils
2
+
3
+ import org.json.JSONObject
4
+ import java.util.concurrent.CopyOnWriteArrayList
5
+
6
+ object RNPropertyManager {
7
+ private val interceptors = CopyOnWriteArrayList<Interceptor>()
8
+
9
+ @Synchronized
10
+ fun addInterceptor(interceptor: Interceptor) {
11
+ interceptors.add(interceptor)
12
+ }
13
+
14
+ fun mergeProperty(properties: JSONObject?): JSONObject {
15
+ return mergeProperty(properties ?: JSONObject(), false)
16
+ }
17
+
18
+ fun mergeProperty(properties: JSONObject, isAuto: Boolean): JSONObject {
19
+ var result = properties
20
+ try {
21
+ for (interceptor in interceptors) {
22
+ result = interceptor.proceed(result, isAuto)
23
+ }
24
+ } catch (e: Exception) {
25
+ QTLog.printStackTrace(e)
26
+ // 如果处理过程中出现异常,返回原始properties
27
+ return properties
28
+ }
29
+ return result
30
+ }
31
+
32
+ interface Interceptor {
33
+ fun proceed(properties: JSONObject, isAuto: Boolean): JSONObject
34
+ }
35
+ }
@@ -0,0 +1,162 @@
1
+ package com.quicktrackinganalyticsmodule.utils
2
+
3
+ import android.annotation.SuppressLint
4
+ import android.graphics.Matrix
5
+ import android.graphics.PointF
6
+ import android.graphics.Rect
7
+ import android.view.View
8
+ import android.view.ViewGroup
9
+ import com.facebook.react.bridge.JSApplicationIllegalArgumentException
10
+ import com.facebook.react.bridge.UiThreadUtil
11
+ import com.facebook.react.touch.ReactHitSlopView
12
+ import com.facebook.react.uimanager.PointerEvents
13
+ import com.facebook.react.uimanager.ReactCompoundView
14
+ import com.facebook.react.uimanager.ReactCompoundViewGroup
15
+ import com.facebook.react.uimanager.ReactPointerEventsView
16
+
17
+ object RNTouchTargetHelper {
18
+ private val mEventCoords = FloatArray(2)
19
+ private val mInverseMatrix = Matrix()
20
+ private val mMatrixTransformCoords = FloatArray(2)
21
+ private val mTempPoint = PointF()
22
+
23
+ fun findTargetTagForTouch(eventX: Float, eventY: Float, viewGroup: ViewGroup): Int {
24
+ return findTargetTagAndCoordinatesForTouch(eventX, eventY, viewGroup, mEventCoords)
25
+ }
26
+
27
+ fun findTargetTagAndCoordinatesForTouch(
28
+ eventX: Float,
29
+ eventY: Float,
30
+ viewGroup: ViewGroup,
31
+ viewCoords: FloatArray
32
+ ): Int {
33
+ UiThreadUtil.assertOnUiThread()
34
+ val targetTag = viewGroup.id
35
+ viewCoords[0] = eventX
36
+ viewCoords[1] = eventY
37
+ val nativeTargetView = findTouchTargetView(viewCoords, viewGroup)
38
+ val reactTargetView = findClosestReactAncestor(nativeTargetView)
39
+ return if (reactTargetView != null) {
40
+ getTouchTargetForView(reactTargetView, viewCoords[0], viewCoords[1])
41
+ } else {
42
+ targetTag
43
+ }
44
+ }
45
+
46
+ @SuppressLint("ResourceType")
47
+ fun findClosestReactAncestor(view: View?): View? {
48
+ var currentView = view
49
+ while (currentView != null && currentView.id <= 0) {
50
+ currentView = currentView.parent as? View
51
+ }
52
+ return currentView
53
+ }
54
+
55
+ fun findTouchTargetView(eventCoords: FloatArray, viewGroup: ViewGroup): View {
56
+ for (i in viewGroup.childCount - 1 downTo 0) {
57
+ val child = viewGroup.getChildAt(i)
58
+ val childPoint = mTempPoint
59
+ if (isTransformedTouchPointInView(eventCoords[0], eventCoords[1], viewGroup, child, childPoint)) {
60
+ val restoreX = eventCoords[0]
61
+ val restoreY = eventCoords[1]
62
+ eventCoords[0] = childPoint.x
63
+ eventCoords[1] = childPoint.y
64
+ val targetView = findTouchTargetViewWithPointerEvents(eventCoords, child)
65
+ if (targetView != null) {
66
+ return targetView
67
+ }
68
+ eventCoords[0] = restoreX
69
+ eventCoords[1] = restoreY
70
+ }
71
+ }
72
+ return viewGroup
73
+ }
74
+
75
+ private fun isTransformedTouchPointInView(
76
+ x: Float,
77
+ y: Float,
78
+ parent: ViewGroup,
79
+ child: View,
80
+ outLocalPoint: PointF
81
+ ): Boolean {
82
+ var localX = (parent.scrollX + x) - child.left
83
+ var localY = (parent.scrollY + y) - child.top
84
+ val matrix = child.matrix
85
+ if (!matrix.isIdentity) {
86
+ val localXY = mMatrixTransformCoords
87
+ localXY[0] = localX
88
+ localXY[1] = localY
89
+ val inverseMatrix = mInverseMatrix
90
+ matrix.invert(inverseMatrix)
91
+ inverseMatrix.mapPoints(localXY)
92
+ localX = localXY[0]
93
+ localY = localXY[1]
94
+ }
95
+
96
+ return when {
97
+ child is ReactHitSlopView && child.hitSlopRect != null -> {
98
+ val hitSlopRect = child.hitSlopRect
99
+ if (localX < -hitSlopRect!!.left ||
100
+ localX >= (child.right - child.left + hitSlopRect.right) ||
101
+ localY < -hitSlopRect.top ||
102
+ localY >= (child.bottom - child.top + hitSlopRect.bottom)) {
103
+ false
104
+ } else {
105
+ outLocalPoint.set(localX, localY)
106
+ true
107
+ }
108
+ }
109
+ localX < 0f || localX >= (child.right - child.left) ||
110
+ localY < 0f || localY >= (child.bottom - child.top) -> false
111
+ else -> {
112
+ outLocalPoint.set(localX, localY)
113
+ true
114
+ }
115
+ }
116
+ }
117
+
118
+ private fun findTouchTargetViewWithPointerEvents(eventCoords: FloatArray, view: View): View? {
119
+ val pointerEvents = if (view is ReactPointerEventsView) {
120
+ view.pointerEvents
121
+ } else {
122
+ PointerEvents.AUTO
123
+ }
124
+
125
+ return when (pointerEvents) {
126
+ PointerEvents.NONE -> null
127
+ PointerEvents.BOX_ONLY -> view
128
+ PointerEvents.BOX_NONE -> {
129
+ if (view is ViewGroup) {
130
+ val targetView = findTouchTargetView(eventCoords, view)
131
+ if (targetView != view) {
132
+ return targetView
133
+ }
134
+ if (view !is ReactCompoundView ||
135
+ view.reactTagForTouch(eventCoords[0], eventCoords[1]) == view.id) {
136
+ return null
137
+ }
138
+ return view
139
+ }
140
+ null
141
+ }
142
+ PointerEvents.AUTO -> {
143
+ if ((view !is ReactCompoundViewGroup ||
144
+ !view.interceptsTouchEvent(eventCoords[0], eventCoords[1])) &&
145
+ view is ViewGroup) {
146
+ findTouchTargetView(eventCoords, view)
147
+ } else {
148
+ view
149
+ }
150
+ }
151
+ else -> throw JSApplicationIllegalArgumentException("Unknown pointer event type: $pointerEvents")
152
+ }
153
+ }
154
+
155
+ fun getTouchTargetForView(targetView: View, eventX: Float, eventY: Float): Int {
156
+ return if (targetView is ReactCompoundView) {
157
+ targetView.reactTagForTouch(eventX, eventY)
158
+ } else {
159
+ targetView.id
160
+ }
161
+ }
162
+ }
@@ -0,0 +1,170 @@
1
+ package com.quicktrackinganalyticsmodule.utils
2
+
3
+ import android.util.Log
4
+ import com.facebook.react.bridge.Arguments
5
+ import com.facebook.react.bridge.ReadableMap
6
+ import com.facebook.react.bridge.ReadableNativeMap
7
+ import com.facebook.react.bridge.WritableMap
8
+ import org.json.JSONArray
9
+ import org.json.JSONObject
10
+ import java.security.MessageDigest
11
+
12
+ object RNUtils {
13
+ const val TAG = "QuickTracking == "
14
+
15
+ /**
16
+ * ReadableMap 转换成 JSONObject
17
+ */
18
+ fun convertToJSONObject(params: ReadableMap?): JSONObject? {
19
+ if (params == null) {
20
+ return null
21
+ }
22
+ var json: JSONObject? = null
23
+ var nativeMap: ReadableNativeMap? = null
24
+ try {
25
+ nativeMap = params as ReadableNativeMap
26
+ json = JSONObject(params.toString()).getJSONObject("NativeMap")
27
+ } catch (e: Exception) {
28
+ Log.e(TAG, "JSON 解析失败!", e)
29
+ val superName = nativeMap?.javaClass?.superclass?.simpleName
30
+ try {
31
+ json = JSONObject(params.toString()).getJSONObject(superName!!)
32
+ } catch (e1: Exception) {
33
+ Log.e(TAG, "JSON 解析失败!", e1)
34
+ }
35
+ }
36
+ return json
37
+ }
38
+
39
+ /**
40
+ * JSONObject 转换成 WritableMap
41
+ */
42
+ fun convertToWritableMap(json: JSONObject?): WritableMap? {
43
+ if (json == null || json.length() == 0) {
44
+ return null
45
+ }
46
+ val writableMap = Arguments.createMap()
47
+ val it = json.keys()
48
+ while (it.hasNext()) {
49
+ try {
50
+ val key = it.next()
51
+ writableMap.putString(key, json.optString(key))
52
+ } catch (e: Exception) {
53
+ QTLog.i(TAG, "JSON to WritableMap 解析失败!", e as Any)
54
+ }
55
+ }
56
+ return writableMap
57
+ }
58
+
59
+ /**
60
+ * ReadableMap 转换成 HashMap
61
+ */
62
+ fun convertToHashMap(params: ReadableMap?): HashMap<String, Any?>? {
63
+ if (params == null) {
64
+ return null
65
+ }
66
+ var map: HashMap<String, Any?>? = null
67
+ try {
68
+ map = (params as ReadableNativeMap).toHashMap()
69
+ } catch (e: Exception) {
70
+ Log.e(TAG, "ReadableMap to HashMap 解析失败!", e)
71
+ }
72
+ return map
73
+ }
74
+
75
+ /**
76
+ * merge JSONObject
77
+ */
78
+ fun mergeJSONObject(source: JSONObject, dest: JSONObject) {
79
+ try {
80
+ val sourceIterator = source.keys()
81
+ while (sourceIterator.hasNext()) {
82
+ val key = sourceIterator.next()
83
+ val value = source.get(key)
84
+ dest.put(key, value)
85
+ }
86
+ } catch (e: Exception) {
87
+ Log.e(TAG, "JSONObject Merge失败!", e)
88
+ }
89
+ }
90
+
91
+ fun convertToMap(jsonObject: JSONObject): Map<String, Any>? {
92
+ return try {
93
+ val map = HashMap<String, Any>()
94
+ val keys = jsonObject.keys()
95
+ while (keys.hasNext()) {
96
+ val key = keys.next()
97
+ val value = jsonObject.get(key)
98
+ map[key] = when (value) {
99
+ is JSONArray -> toList(value)
100
+ is JSONObject -> toMap(value)
101
+ else -> value
102
+ } ?: continue
103
+ }
104
+ map
105
+ } catch (e: Exception) {
106
+ QTLog.printStackTrace(e)
107
+ null
108
+ }
109
+ }
110
+
111
+ fun toList(jsonArray: JSONArray): List<Any>? {
112
+ return try {
113
+ val list = ArrayList<Any>()
114
+ for (i in 0 until jsonArray.length()) {
115
+ val obj = jsonArray.get(i)
116
+ val processedObj = when (obj) {
117
+ is JSONArray -> toList(obj)
118
+ is JSONObject -> toMap(obj)
119
+ else -> obj
120
+ } ?: continue
121
+ list.add(processedObj)
122
+ }
123
+ list
124
+ } catch (e: Exception) {
125
+ QTLog.printStackTrace(e)
126
+ null
127
+ }
128
+ }
129
+
130
+ fun toMap(jsonObject: JSONObject): Map<String, Any>? {
131
+ return try {
132
+ val map = HashMap<String, Any>()
133
+ val keysItr = jsonObject.keys()
134
+ while (keysItr.hasNext()) {
135
+ val key = keysItr.next()
136
+ val value = jsonObject.get(key)
137
+ map[key] = when (value) {
138
+ is JSONArray -> toList(value)
139
+ is JSONObject -> toMap(value)
140
+ else -> value
141
+ } ?: continue
142
+ }
143
+ map
144
+ } catch (e: Exception) {
145
+ QTLog.printStackTrace(e)
146
+ null
147
+ }
148
+ }
149
+
150
+ fun MD5(str: String?): String? {
151
+ if (str == null) return null
152
+ return try {
153
+ val defaultBytes = str.toByteArray()
154
+ val algorithm = MessageDigest.getInstance("MD5")
155
+ algorithm.reset()
156
+ algorithm.update(defaultBytes)
157
+ val messageDigest = algorithm.digest()
158
+ val hexString = StringBuilder()
159
+ for (b in messageDigest) {
160
+ hexString.append(String.format("%02X", b))
161
+ }
162
+ hexString.toString()
163
+ } catch (e: Exception) {
164
+ str.replace(Regex("[^a-zA-Z0-9._]"), "")
165
+ } catch (e: Throwable) {
166
+ Log.e(TAG, "MD5 e is $e")
167
+ null
168
+ }
169
+ }
170
+ }