@react-native-ama/core 2.0.0-beta.1 → 2.0.0-beta.2
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/ama.config.json +17 -0
- package/android/build.gradle +43 -0
- package/android/src/debug/AndroidManifest.xml +2 -0
- package/android/src/debug/java/expo/modules/ama/ReactNativeAmaModule.kt +544 -0
- package/android/src/debug/java/expo/modules/ama/ReactNativeAmaView.kt +30 -0
- package/android/src/debug/java/expo/modules/ama/highlight.kt +189 -0
- package/android/src/debug/java/expo/modules/ama/logger.kt +25 -0
- package/android/src/debug/java/expo/modules/ama/nodesGrabber.kt +664 -0
- package/expo-module.config.json +9 -0
- package/ios/Highlight.swift +264 -0
- package/ios/Logger.swift +31 -0
- package/ios/NodesGrabber.swift +733 -0
- package/ios/ReactNativeAma.podspec +29 -0
- package/ios/ReactNativeAmaModule.swift +568 -0
- package/ios/ReactNativeAmaView.swift +38 -0
- package/ios/TapGesture.swift +107 -0
- package/package.json +8 -2
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
package expo.modules.ama
|
|
2
|
+
|
|
3
|
+
import android.app.Activity
|
|
4
|
+
import android.graphics.*
|
|
5
|
+
import android.graphics.drawable.Drawable
|
|
6
|
+
import android.graphics.drawable.LayerDrawable
|
|
7
|
+
import android.graphics.drawable.ShapeDrawable
|
|
8
|
+
import android.graphics.drawable.shapes.RectShape
|
|
9
|
+
import android.view.View
|
|
10
|
+
import expo.modules.kotlin.AppContext
|
|
11
|
+
import java.util.concurrent.ConcurrentHashMap
|
|
12
|
+
|
|
13
|
+
class Highlight(private val appContext: AppContext) {
|
|
14
|
+
private val originalBackgrounds = ConcurrentHashMap<Int, Drawable?>()
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Highlight the view with the given ID.
|
|
18
|
+
* @param viewId the Android view ID
|
|
19
|
+
* @param mode "background" | "border" | "both"
|
|
20
|
+
*/
|
|
21
|
+
fun highlight(viewId: Int, mode: String, hexColor: String, gap: Int = 0, lineWidth: Float = 6f, issueCount: Int = 1) {
|
|
22
|
+
val activity: Activity = appContext.currentActivity ?: return
|
|
23
|
+
val color = hexColor.toColor()
|
|
24
|
+
|
|
25
|
+
activity.runOnUiThread {
|
|
26
|
+
val target = activity.findViewById<View>(viewId) ?: return@runOnUiThread
|
|
27
|
+
|
|
28
|
+
val view = activity.findViewById<View>(viewId) ?: return@runOnUiThread
|
|
29
|
+
|
|
30
|
+
view.background?.let { bg -> originalBackgrounds.putIfAbsent(viewId, bg) }
|
|
31
|
+
|
|
32
|
+
when (mode) {
|
|
33
|
+
"background" -> applyStripyBackground(target, color)
|
|
34
|
+
"border" -> applyRedBorderOverlay(target, color, gap, lineWidth, issueCount)
|
|
35
|
+
else -> {
|
|
36
|
+
applyRedBorderOverlay(target, color, gap, lineWidth, issueCount)
|
|
37
|
+
applyStripyBackground(target, color)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
fun clearHighlight(viewId: Int) {
|
|
44
|
+
val activity: Activity = appContext.currentActivity ?: return
|
|
45
|
+
|
|
46
|
+
activity.runOnUiThread {
|
|
47
|
+
val view = activity.findViewById<View>(viewId) ?: return@runOnUiThread
|
|
48
|
+
|
|
49
|
+
val original = originalBackgrounds.remove(viewId)
|
|
50
|
+
view.background = original
|
|
51
|
+
|
|
52
|
+
view.overlay.clear()
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
private fun applyStripyBackground(view: View, color: Int?) {
|
|
57
|
+
val originalBackground = view.background
|
|
58
|
+
|
|
59
|
+
val stripeWidth = 5f
|
|
60
|
+
val gapWidth = 25f
|
|
61
|
+
val bmpWidth = 150
|
|
62
|
+
val bmpHeight = bmpWidth
|
|
63
|
+
|
|
64
|
+
val bmp = Bitmap.createBitmap(bmpWidth, bmpHeight, Bitmap.Config.ARGB_8888)
|
|
65
|
+
val canvas = Canvas(bmp)
|
|
66
|
+
|
|
67
|
+
val stripePaint =
|
|
68
|
+
Paint().apply {
|
|
69
|
+
this.color = color ?: Color.RED
|
|
70
|
+
isAntiAlias = true
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
val canvasCenter = bmpWidth / 2f
|
|
74
|
+
canvas.save()
|
|
75
|
+
canvas.rotate(-45f, canvasCenter, canvasCenter)
|
|
76
|
+
|
|
77
|
+
val extendedSize = (bmpWidth * 1.5f)
|
|
78
|
+
var y = -extendedSize
|
|
79
|
+
while (y < extendedSize) {
|
|
80
|
+
canvas.drawRect(-extendedSize, y, extendedSize, y + stripeWidth, stripePaint)
|
|
81
|
+
y += stripeWidth + gapWidth
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
canvas.restore()
|
|
85
|
+
|
|
86
|
+
val shader = BitmapShader(bmp, Shader.TileMode.MIRROR, Shader.TileMode.REPEAT)
|
|
87
|
+
|
|
88
|
+
val backgroundPaint = Paint().apply { this.shader = shader }
|
|
89
|
+
|
|
90
|
+
val stripedDrawable =
|
|
91
|
+
object : Drawable() {
|
|
92
|
+
override fun draw(c: Canvas) = c.drawRect(bounds, backgroundPaint)
|
|
93
|
+
|
|
94
|
+
override fun setAlpha(alpha: Int) {
|
|
95
|
+
backgroundPaint.alpha = alpha
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
override fun setColorFilter(cf: ColorFilter?) {
|
|
99
|
+
backgroundPaint.colorFilter = cf
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
@Deprecated(
|
|
103
|
+
"Deprecated in Java",
|
|
104
|
+
ReplaceWith("PixelFormat.TRANSLUCENT", "android.graphics.PixelFormat")
|
|
105
|
+
)
|
|
106
|
+
override fun getOpacity(): Int = PixelFormat.TRANSLUCENT
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (originalBackground == null) {
|
|
110
|
+
view.background = stripedDrawable
|
|
111
|
+
} else {
|
|
112
|
+
val layers = arrayOf(originalBackground, stripedDrawable)
|
|
113
|
+
view.background = LayerDrawable(layers)
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
private fun applyRedBorderOverlay(view: View, color: Int?, gap: Int, lineWidth: Float = 6f, issueCount: Int = 1) {
|
|
118
|
+
view.overlay.clear()
|
|
119
|
+
|
|
120
|
+
val stroke = lineWidth
|
|
121
|
+
val half = (stroke / 2).toInt()
|
|
122
|
+
val shape =
|
|
123
|
+
ShapeDrawable(RectShape()).apply {
|
|
124
|
+
paint.apply {
|
|
125
|
+
this.color = color ?: Color.RED
|
|
126
|
+
style = Paint.Style.STROKE
|
|
127
|
+
strokeWidth = stroke
|
|
128
|
+
// Make the border dotted
|
|
129
|
+
pathEffect = DashPathEffect(floatArrayOf(stroke * 2, stroke * 2), 0f)
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
val left = -gap
|
|
134
|
+
val top = -gap
|
|
135
|
+
val right = view.width - half + gap
|
|
136
|
+
val bottom = view.height - half + gap
|
|
137
|
+
|
|
138
|
+
shape.setBounds(left, top, right, bottom)
|
|
139
|
+
view.overlay.add(shape)
|
|
140
|
+
|
|
141
|
+
val iconDrawable = object : Drawable() {
|
|
142
|
+
val fillPaint = Paint().apply {
|
|
143
|
+
this.color = color ?: Color.RED
|
|
144
|
+
style = Paint.Style.FILL
|
|
145
|
+
isAntiAlias = true
|
|
146
|
+
}
|
|
147
|
+
val textPaint = Paint().apply {
|
|
148
|
+
this.color = Color.WHITE
|
|
149
|
+
style = Paint.Style.FILL
|
|
150
|
+
textSize = 28f
|
|
151
|
+
textAlign = Paint.Align.CENTER
|
|
152
|
+
isAntiAlias = true
|
|
153
|
+
typeface = android.graphics.Typeface.DEFAULT_BOLD
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
override fun draw(canvas: Canvas) {
|
|
157
|
+
val badgeSize = 48f
|
|
158
|
+
val centerX = right.toFloat()
|
|
159
|
+
val centerY = top.toFloat()
|
|
160
|
+
|
|
161
|
+
// Draw circle badge
|
|
162
|
+
canvas.drawCircle(centerX, centerY, badgeSize / 2, fillPaint)
|
|
163
|
+
|
|
164
|
+
// Draw issue count text centered in circle
|
|
165
|
+
val textBounds = android.graphics.Rect()
|
|
166
|
+
val countText = issueCount.toString()
|
|
167
|
+
textPaint.getTextBounds(countText, 0, countText.length, textBounds)
|
|
168
|
+
val textY = centerY + textBounds.height() / 2f
|
|
169
|
+
canvas.drawText(countText, centerX, textY, textPaint)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
override fun setAlpha(alpha: Int) {}
|
|
173
|
+
override fun setColorFilter(colorFilter: ColorFilter?) {}
|
|
174
|
+
override fun getOpacity(): Int = PixelFormat.TRANSLUCENT
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// We need to set bounds for the icon drawable too, usually view bounds is fine as we draw relative to coordinates
|
|
178
|
+
iconDrawable.setBounds(0, 0, view.width, view.height)
|
|
179
|
+
view.overlay.add(iconDrawable)
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
fun String.toColor(): Int {
|
|
184
|
+
if (this.length == 4 && this.startsWith("#")) {
|
|
185
|
+
val expandedHex = "#" + this[1] + this[1] + this[2] + this[2] + this[3] + this[3]
|
|
186
|
+
return Color.parseColor(expandedHex)
|
|
187
|
+
}
|
|
188
|
+
return Color.parseColor(this)
|
|
189
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
package expo.modules.ama
|
|
2
|
+
|
|
3
|
+
import android.util.Log
|
|
4
|
+
|
|
5
|
+
object Logger {
|
|
6
|
+
public fun info(fn: String, message: String, extra: String? = null) {
|
|
7
|
+
if (extra.isNullOrEmpty()) {
|
|
8
|
+
Log.i("[ReactNative AMA]: ", fn + " " + message)
|
|
9
|
+
} else {
|
|
10
|
+
Log.i("[ReactNative AMA]: ", fn + " " + message + " >>> " + extra)
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
public fun info2(fn: String, message: String) {
|
|
15
|
+
Logger.info(" " + fn, message)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
public fun debug(fn: String, message: String) {
|
|
19
|
+
Log.d("[ReactNative AMA]: ", fn + " " + message)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
public fun error(fn: String, message: String) {
|
|
23
|
+
Log.e("[ReactNative AMA - Error]: ", fn + " " + message)
|
|
24
|
+
}
|
|
25
|
+
}
|