react-native-advanced-text 0.1.9 → 0.1.10

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.
@@ -9,11 +9,9 @@ import android.text.TextPaint
9
9
  import android.text.method.LinkMovementMethod
10
10
  import android.text.style.ClickableSpan
11
11
  import android.text.style.BackgroundColorSpan
12
- import android.text.style.ForegroundColorSpan
13
12
  import android.util.AttributeSet
14
13
  import android.util.Log
15
- import android.view.ActionMode
16
- import android.view.Menu
14
+ import android.view.ContextMenu
17
15
  import android.view.MenuItem
18
16
  import android.view.View
19
17
  import android.widget.TextView
@@ -22,7 +20,7 @@ import com.facebook.react.bridge.ReactContext
22
20
  import com.facebook.react.uimanager.events.RCTEventEmitter
23
21
  import android.text.Selection
24
22
 
25
- class AdvancedTextView : TextView {
23
+ class AdvancedTextView : TextView, View.OnCreateContextMenuListener {
26
24
 
27
25
  private val TAG = "AdvancedTextView"
28
26
 
@@ -30,7 +28,7 @@ class AdvancedTextView : TextView {
30
28
  private var menuOptions: List<String> = emptyList()
31
29
  private var indicatorWordIndex: Int = -1
32
30
  private var lastSelectedText: String = ""
33
- private var customActionMode: ActionMode? = null
31
+ private var isSelectionEnabled: Boolean = true
34
32
 
35
33
  constructor(context: Context?) : super(context) { init() }
36
34
  constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) { init() }
@@ -39,65 +37,24 @@ class AdvancedTextView : TextView {
39
37
  private fun init() {
40
38
  Log.d(TAG, "AdvancedTextView initialized")
41
39
 
42
- // Set default text appearance - DON'T set black color here
40
+ // Set default text appearance
41
+ setTextColor(Color.BLACK)
43
42
  textSize = 16f
44
43
  setPadding(16, 16, 16, 16)
45
44
 
46
45
  movementMethod = LinkMovementMethod.getInstance()
47
46
  setTextIsSelectable(true)
47
+ setOnCreateContextMenuListener(this)
48
48
 
49
- // Use custom action mode for selection menu
50
- customSelectionActionModeCallback = object : ActionMode.Callback {
51
- override fun onCreateActionMode(mode: ActionMode?, menu: Menu?): Boolean {
52
- Log.d(TAG, "onCreateActionMode triggered")
53
- customActionMode = mode
54
- return true
55
- }
56
-
57
- override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?): Boolean {
58
- Log.d(TAG, "onPrepareActionMode triggered")
59
- menu?.clear()
60
-
61
- val selectionStart = selectionStart
62
- val selectionEnd = selectionEnd
63
-
64
- if (selectionStart >= 0 && selectionEnd >= 0 && selectionStart != selectionEnd) {
65
- lastSelectedText = text.subSequence(selectionStart, selectionEnd).toString()
66
- Log.d(TAG, "User selected text: '$lastSelectedText'")
67
- Log.d(TAG, "Menu options available: $menuOptions")
68
-
69
- menuOptions.forEachIndexed { index, option ->
70
- menu?.add(0, index, index, option)
71
- }
72
-
73
- sendSelectionEvent(lastSelectedText, "selection")
74
- return true
75
- }
76
- return false
77
- }
78
-
79
- override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?): Boolean {
80
- item?.let {
81
- val menuItemText = it.title.toString()
82
- Log.d(TAG, "Menu item clicked: $menuItemText")
83
- sendSelectionEvent(lastSelectedText, menuItemText)
84
- mode?.finish()
85
- return true
86
- }
87
- return false
88
- }
89
-
90
- override fun onDestroyActionMode(mode: ActionMode?) {
91
- Log.d(TAG, "onDestroyActionMode")
92
- customActionMode = null
93
- }
94
- }
49
+ // Ensure minimum height for visibility during debugging
50
+ minHeight = 100
95
51
  }
96
52
 
97
53
  fun setAdvancedText(text: String) {
98
54
  Log.d(TAG, "setAdvancedText: $text (length=${text.length})")
99
55
  this.text = text
100
56
  updateTextWithHighlights()
57
+ // Force layout update
101
58
  requestLayout()
102
59
  invalidate()
103
60
  }
@@ -161,16 +118,16 @@ class AdvancedTextView : TextView {
161
118
 
162
119
  if (wordIndex == indicatorWordIndex) {
163
120
  Log.d(TAG, "Applying indicator span to word '$word' at index $wordIndex")
164
- // Apply red color to the indicator word
121
+
165
122
  spannableString.setSpan(
166
- ForegroundColorSpan(Color.RED),
123
+ IndicatorSpan(),
167
124
  wordStart,
168
125
  wordEnd,
169
126
  Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
170
127
  )
171
128
  }
172
129
 
173
- // Make words clickable
130
+ // clickable span
174
131
  spannableString.setSpan(
175
132
  WordClickableSpan(wordIndex, word),
176
133
  wordStart,
@@ -187,6 +144,39 @@ class AdvancedTextView : TextView {
187
144
  Log.d(TAG, "Text updated with spans")
188
145
  }
189
146
 
147
+ override fun onCreateContextMenu(menu: ContextMenu?, v: View?, menuInfo: ContextMenu.ContextMenuInfo?) {
148
+ val selectionStart = selectionStart
149
+ val selectionEnd = selectionEnd
150
+
151
+ Log.d(TAG, "onCreateContextMenu triggered. selectionStart=$selectionStart selectionEnd=$selectionEnd")
152
+
153
+ if (selectionStart >= 0 && selectionEnd >= 0 && selectionStart != selectionEnd) {
154
+ lastSelectedText = text.subSequence(selectionStart, selectionEnd).toString()
155
+
156
+ Log.d(TAG, "User selected text: '$lastSelectedText'")
157
+ Log.d(TAG, "Menu options available: $menuOptions")
158
+
159
+ menu?.clear()
160
+
161
+ menuOptions.forEachIndexed { index, option ->
162
+ menu?.add(0, index, index, option)?.setOnMenuItemClickListener {
163
+ Log.d(TAG, "Menu item clicked: $option")
164
+ onMenuItemClick(it, lastSelectedText)
165
+ true
166
+ }
167
+ }
168
+
169
+ sendSelectionEvent(lastSelectedText, "selection")
170
+ }
171
+ }
172
+
173
+ private fun onMenuItemClick(item: MenuItem, selectedText: String): Boolean {
174
+ val menuItemText = menuOptions[item.itemId]
175
+ Log.d(TAG, "onMenuItemClick: menuOption='$menuItemText', selectedText='$selectedText'")
176
+ sendSelectionEvent(selectedText, menuItemText)
177
+ return true
178
+ }
179
+
190
180
  private fun sendSelectionEvent(selectedText: String, eventType: String) {
191
181
  Log.d(TAG, "sendSelectionEvent -> eventType='$eventType' selectedText='$selectedText'")
192
182
 
@@ -211,17 +201,24 @@ class AdvancedTextView : TextView {
211
201
 
212
202
  override fun onClick(widget: View) {
213
203
  Log.d(TAG, "Word clicked: '$word' (index=$wordIndex)")
214
- // Clear any selection first to prevent interference
215
- val spannable = widget as? TextView
216
- spannable?.let {
217
- Selection.removeSelection(it.text as? android.text.Spannable)
218
- }
219
204
  sendWordPressEvent(word, wordIndex)
220
205
  }
221
206
 
222
207
  override fun updateDrawState(ds: TextPaint) {
223
208
  super.updateDrawState(ds)
224
- // Don't change the color - let ForegroundColorSpan handle it
209
+ ds.color = currentTextColor
210
+ ds.isUnderlineText = false
211
+ }
212
+ }
213
+
214
+ private inner class IndicatorSpan : ClickableSpan() {
215
+ override fun onClick(widget: View) {
216
+ Log.d(TAG, "IndicatorSpan clicked (shouldn't trigger action)")
217
+ }
218
+
219
+ override fun updateDrawState(ds: TextPaint) {
220
+ ds.color = Color.RED
221
+ ds.isFakeBoldText = true
225
222
  ds.isUnderlineText = false
226
223
  }
227
224
  }
@@ -1,7 +1,7 @@
1
1
  // File: AdvancedTextViewManager.kt
2
+ // This should be the ONLY content in this file
2
3
  package com.advancedtext
3
4
 
4
- import android.graphics.Color
5
5
  import android.view.ViewGroup
6
6
  import com.facebook.react.bridge.ReadableArray
7
7
  import com.facebook.react.module.annotations.ReactModule
@@ -31,10 +31,10 @@ class AdvancedTextViewManager : SimpleViewManager<AdvancedTextView>(),
31
31
 
32
32
  public override fun createViewInstance(context: ThemedReactContext): AdvancedTextView {
33
33
  val view = AdvancedTextView(context)
34
- // Set layout params for proper sizing
34
+ // Set default layout params to ensure the view is visible
35
35
  view.layoutParams = ViewGroup.LayoutParams(
36
36
  ViewGroup.LayoutParams.MATCH_PARENT,
37
- ViewGroup.LayoutParams.WRAP_CONTENT // Changed to WRAP_CONTENT for auto height
37
+ ViewGroup.LayoutParams.WRAP_CONTENT
38
38
  )
39
39
  return view
40
40
  }
@@ -81,15 +81,7 @@ class AdvancedTextViewManager : SimpleViewManager<AdvancedTextView>(),
81
81
  view?.setIndicatorWordIndex(index)
82
82
  }
83
83
 
84
- // Handle color prop from React Native style
85
- @ReactProp(name = "color", customType = "Color")
86
- fun setColor(view: AdvancedTextView?, color: Int?) {
87
- color?.let {
88
- view?.setTextColor(it)
89
- }
90
- }
91
-
92
- // Register custom events
84
+ // Add this method to register custom events
93
85
  override fun getExportedCustomDirectEventTypeConstants(): Map<String, Any> {
94
86
  return mapOf(
95
87
  "onWordPress" to mapOf("registrationName" to "onWordPress"),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-advanced-text",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "description": " Advanced text component for React Native with custom select options.",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",