@dr33m/react-native-readium 5.0.0-rc.24 → 5.0.0-rc.25
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.
|
@@ -45,7 +45,7 @@ abstract class BaseReaderFragment : Fragment() {
|
|
|
45
45
|
// True while the user has an active text selection.
|
|
46
46
|
// applyDecorations injects JS into the EPUB WebView; doing so while the user
|
|
47
47
|
// is dragging selection handles causes the selection to jump or reset.
|
|
48
|
-
|
|
48
|
+
protected var isUserSelecting = false
|
|
49
49
|
|
|
50
50
|
// Track active decoration listeners to avoid duplicates
|
|
51
51
|
private val activeDecorationGroups = mutableSetOf<String>()
|
|
@@ -112,8 +112,8 @@ abstract class BaseReaderFragment : Fragment() {
|
|
|
112
112
|
// Apply any pending decorations now that navigator is ready
|
|
113
113
|
pendingDecorations?.let { applyDecorations(it) }
|
|
114
114
|
|
|
115
|
-
//
|
|
116
|
-
|
|
115
|
+
// Selection detection is handled via ActionMode callbacks in EpubReaderFragment,
|
|
116
|
+
// not polling — see onSelectionActionModeCreated/Destroyed.
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
override fun onHiddenChanged(hidden: Boolean) {
|
|
@@ -317,64 +317,45 @@ abstract class BaseReaderFragment : Fragment() {
|
|
|
317
317
|
}
|
|
318
318
|
|
|
319
319
|
/**
|
|
320
|
-
*
|
|
320
|
+
* Called by [EpubReaderFragment] when the WebView's ActionMode is created
|
|
321
|
+
* (i.e. the user selects text). Queries the selection once and emits a
|
|
322
|
+
* [SelectionChanged] event so the React Native side can show the highlight menu.
|
|
321
323
|
*
|
|
322
|
-
*
|
|
323
|
-
*
|
|
324
|
-
*
|
|
325
|
-
* [SelectableNavigator.currentSelection], which must be called on-demand.
|
|
326
|
-
* Polling is the least-invasive way to detect changes without forking the
|
|
327
|
-
* Readium toolkit.
|
|
324
|
+
* This replaces the old 500ms polling loop which executed JavaScript in the
|
|
325
|
+
* WebView every tick and disrupted the browser's selection state, causing
|
|
326
|
+
* the selection to glitch/jump while dragging handles.
|
|
328
327
|
*/
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
val selectableNavigator = navigator as? SelectableNavigator
|
|
341
|
-
if (selectableNavigator == null) continue
|
|
342
|
-
|
|
343
|
-
val currentSelection = try {
|
|
344
|
-
selectableNavigator.currentSelection()
|
|
345
|
-
} catch (e: Exception) {
|
|
346
|
-
android.util.Log.w("BaseReaderFragment", "Error getting selection: ${e.message}")
|
|
347
|
-
null
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
val currentLocator = currentSelection?.locator
|
|
351
|
-
val currentText = currentLocator?.text?.highlight
|
|
352
|
-
|
|
353
|
-
// Keep the guard flag in sync so TTS decoration skips DOM updates
|
|
354
|
-
// while the user is dragging selection handles.
|
|
355
|
-
isUserSelecting = currentLocator != null
|
|
356
|
-
|
|
357
|
-
// Check if selection has changed
|
|
358
|
-
val hasChanged = when {
|
|
359
|
-
previousSelection == null && currentLocator == null -> false
|
|
360
|
-
previousSelection == null || currentLocator == null -> true
|
|
361
|
-
previousSelection.href != currentLocator.href -> true
|
|
362
|
-
previousSelection.text.highlight != currentText -> true
|
|
363
|
-
else -> false
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
if (hasChanged) {
|
|
367
|
-
channel.send(
|
|
368
|
-
ReaderViewModel.Event.SelectionChanged(
|
|
369
|
-
locator = currentLocator,
|
|
370
|
-
selectedText = currentText
|
|
371
|
-
)
|
|
328
|
+
fun onSelectionActionModeCreated() {
|
|
329
|
+
isUserSelecting = true
|
|
330
|
+
viewLifecycleOwner.lifecycleScope.launch {
|
|
331
|
+
delay(100) // brief delay so the WebView selection stabilises
|
|
332
|
+
if (!isNavigatorReady) return@launch
|
|
333
|
+
val sel = (navigator as? SelectableNavigator)?.currentSelection()
|
|
334
|
+
if (sel != null) {
|
|
335
|
+
channel.send(
|
|
336
|
+
ReaderViewModel.Event.SelectionChanged(
|
|
337
|
+
locator = sel.locator,
|
|
338
|
+
selectedText = sel.locator.text.highlight
|
|
372
339
|
)
|
|
373
|
-
|
|
374
|
-
previousSelection = currentLocator
|
|
375
|
-
}
|
|
340
|
+
)
|
|
376
341
|
}
|
|
377
342
|
}
|
|
378
343
|
}
|
|
379
344
|
|
|
345
|
+
/**
|
|
346
|
+
* Called by [EpubReaderFragment] when the WebView's ActionMode is destroyed
|
|
347
|
+
* (i.e. the user taps away or the selection is dismissed).
|
|
348
|
+
*/
|
|
349
|
+
fun onSelectionActionModeDestroyed() {
|
|
350
|
+
isUserSelecting = false
|
|
351
|
+
viewLifecycleOwner.lifecycleScope.launch {
|
|
352
|
+
channel.send(
|
|
353
|
+
ReaderViewModel.Event.SelectionChanged(
|
|
354
|
+
locator = null,
|
|
355
|
+
selectedText = null
|
|
356
|
+
)
|
|
357
|
+
)
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
380
361
|
}
|
|
@@ -133,11 +133,14 @@ class EpubReaderFragment : VisualReaderFragment() {
|
|
|
133
133
|
suppressNativeSelectionMenu -> selectionActionModeCallback = object : ActionMode.Callback {
|
|
134
134
|
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
|
|
135
135
|
menu.clear()
|
|
136
|
+
onSelectionActionModeCreated()
|
|
136
137
|
return true
|
|
137
138
|
}
|
|
138
139
|
override fun onPrepareActionMode(mode: ActionMode, menu: Menu) = false
|
|
139
140
|
override fun onActionItemClicked(mode: ActionMode, item: MenuItem) = false
|
|
140
|
-
override fun onDestroyActionMode(mode: ActionMode) {
|
|
141
|
+
override fun onDestroyActionMode(mode: ActionMode) {
|
|
142
|
+
onSelectionActionModeDestroyed()
|
|
143
|
+
}
|
|
141
144
|
}
|
|
142
145
|
selectionActions.isNotEmpty() -> selectionActionModeCallback = customSelectionActionModeCallback
|
|
143
146
|
}
|
|
@@ -225,6 +228,8 @@ class EpubReaderFragment : VisualReaderFragment() {
|
|
|
225
228
|
// Clear previous action mappings
|
|
226
229
|
actionIdMap.clear()
|
|
227
230
|
|
|
231
|
+
onSelectionActionModeCreated()
|
|
232
|
+
|
|
228
233
|
// Only add menu items if navigator supports decorations
|
|
229
234
|
if (navigator !is DecorableNavigator) {
|
|
230
235
|
return true
|
|
@@ -283,6 +288,7 @@ class EpubReaderFragment : VisualReaderFragment() {
|
|
|
283
288
|
override fun onDestroyActionMode(mode: ActionMode) {
|
|
284
289
|
// Clean up action mappings
|
|
285
290
|
actionIdMap.clear()
|
|
291
|
+
onSelectionActionModeDestroyed()
|
|
286
292
|
}
|
|
287
293
|
}
|
|
288
294
|
|