Skip to content

Commit 4c368e3

Browse files
authored
Merge pull request #620 from wordpress-mobile/issue/618-onimagedeleted-called-in-sequence
Issue/618 onMediaDeleted called unnecessarily in sequence
2 parents e6fc800 + d15a322 commit 4c368e3

File tree

3 files changed

+78
-5
lines changed

3 files changed

+78
-5
lines changed

aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ import org.wordpress.aztec.util.AztecLog
8888
import org.wordpress.aztec.util.SpanWrapper
8989
import org.wordpress.aztec.util.coerceToHtmlText
9090
import org.wordpress.aztec.watchers.BlockElementWatcher
91-
import org.wordpress.aztec.watchers.DeleteMediaElementWatcher
91+
import org.wordpress.aztec.watchers.DeleteMediaElementWatcherAPI25AndHigher
92+
import org.wordpress.aztec.watchers.DeleteMediaElementWatcherPreAPI25
9293
import org.wordpress.aztec.watchers.EndOfBufferMarkerAdder
9394
import org.wordpress.aztec.watchers.EndOfParagraphMarkerAdder
9495
import org.wordpress.aztec.watchers.FullWidthImageElementWatcher
@@ -445,7 +446,11 @@ class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknownHtmlT
445446
EndOfBufferMarkerAdder.install(this)
446447
ZeroIndexContentWatcher.install(this)
447448

448-
DeleteMediaElementWatcher.install(this)
449+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
450+
DeleteMediaElementWatcherAPI25AndHigher.install(this)
451+
} else {
452+
DeleteMediaElementWatcherPreAPI25.install(this)
453+
}
449454

450455
// History related logging has to happen before the changes in [ParagraphCollapseRemover]
451456
addHistoryLoggingWatcher()
@@ -852,6 +857,13 @@ class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknownHtmlT
852857
return (observationQueue.hasActiveBuckets() && !bypassObservationQueue && (watchersNestingLevel == 1))
853858
}
854859

860+
fun isObservationQueueBeingPopulated() : Boolean {
861+
// TODO: use the value that is going to be published from ObservationQueue.MAXIMUM_TIME_BETWEEN_EVENTS_IN_PATTERN_MS
862+
val MAXIMUM_TIME_BETWEEN_EVENTS_IN_PATTERN_MS = 100
863+
return !observationQueue.isEmpty() &&
864+
((System.currentTimeMillis() - observationQueue.last().timestamp) < MAXIMUM_TIME_BETWEEN_EVENTS_IN_PATTERN_MS)
865+
}
866+
855867
override fun beforeTextChanged(text: CharSequence, start: Int, count: Int, after: Int) {
856868
addWatcherNestingLevel()
857869
if (!isViewInitialized) return
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package org.wordpress.aztec.watchers
2+
3+
import android.text.Editable
4+
import android.text.TextWatcher
5+
import org.wordpress.aztec.AztecText
6+
import org.wordpress.aztec.spans.AztecMediaSpan
7+
import java.lang.ref.WeakReference
8+
9+
class DeleteMediaElementWatcherAPI25AndHigher(aztecText: AztecText) : TextWatcher {
10+
private val aztecTextRef: WeakReference<AztecText?> = WeakReference(aztecText)
11+
private var deleted = false
12+
private var queueHasBeenPopulatedInThisTimeframe = false
13+
private var deletedSpans = ArrayList<AztecMediaSpan>()
14+
15+
override fun beforeTextChanged(text: CharSequence, start: Int, count: Int, after: Int) {
16+
if (aztecTextRef.get()?.isTextChangedListenerDisabled() ?: true) {
17+
return
18+
}
19+
20+
if (count > 0) {
21+
deleted = true
22+
23+
// we need to save the spans for later reference, as these spans are going to not exist anymore by the time
24+
// the afterTextChanged event arrives. So, adding them to a local deletedSpans array.
25+
aztecTextRef.get()?.text?.getSpans(start, start + count, AztecMediaSpan::class.java)
26+
?.forEach {
27+
deletedSpans.add(it)
28+
}
29+
30+
// only call the onMediaDeleted callback if we are sure the ObservationQueue has not been filled with
31+
// platform-only events in a short time. These platform-originated events shall not be confused with
32+
// real user deletions.
33+
aztecTextRef.get()?.postDelayed( object : Runnable {
34+
override fun run() {
35+
if (!queueHasBeenPopulatedInThisTimeframe) {
36+
deletedSpans.forEach { it.onMediaDeleted() }
37+
}
38+
// reset flag
39+
deletedSpans.clear()
40+
queueHasBeenPopulatedInThisTimeframe = false
41+
}
42+
}, 500)
43+
}
44+
}
45+
46+
override fun onTextChanged(text: CharSequence, start: Int, before: Int, count: Int) {
47+
// no op
48+
}
49+
50+
override fun afterTextChanged(text: Editable) {
51+
if (deleted && aztecTextRef.get()?.isObservationQueueBeingPopulated() ?: true) {
52+
queueHasBeenPopulatedInThisTimeframe = true
53+
}
54+
}
55+
56+
companion object {
57+
fun install(text: AztecText) {
58+
text.addTextChangedListener(DeleteMediaElementWatcherAPI25AndHigher(text))
59+
}
60+
}
61+
}

aztec/src/main/kotlin/org/wordpress/aztec/watchers/DeleteMediaElementWatcher.kt renamed to aztec/src/main/kotlin/org/wordpress/aztec/watchers/DeleteMediaElementWatcherPreAPI25.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import org.wordpress.aztec.AztecText
66
import org.wordpress.aztec.spans.AztecMediaSpan
77
import java.lang.ref.WeakReference
88

9-
class DeleteMediaElementWatcher(aztecText: AztecText) : TextWatcher {
9+
class DeleteMediaElementWatcherPreAPI25(aztecText: AztecText) : TextWatcher {
1010
private val aztecTextRef: WeakReference<AztecText?> = WeakReference(aztecText)
1111

1212
override fun beforeTextChanged(text: CharSequence, start: Int, count: Int, after: Int) {
@@ -32,7 +32,7 @@ class DeleteMediaElementWatcher(aztecText: AztecText) : TextWatcher {
3232

3333
companion object {
3434
fun install(text: AztecText) {
35-
text.addTextChangedListener(DeleteMediaElementWatcher(text))
35+
text.addTextChangedListener(DeleteMediaElementWatcherPreAPI25(text))
3636
}
3737
}
38-
}
38+
}

0 commit comments

Comments
 (0)