That fuck shit the fascists are using
at master 98 lines 3.1 kB view raw
1package org.tm.archive.components 2 3import android.text.Annotation 4import android.text.Editable 5import android.text.Spannable 6import android.text.Spanned 7import android.text.TextUtils 8import android.text.TextWatcher 9import org.signal.core.util.StringUtil 10import org.tm.archive.conversation.MessageStyler 11import org.tm.archive.conversation.MessageStyler.isSupportedStyle 12 13/** 14 * Formatting should only grow when appending until a white space character is entered/pasted. 15 * 16 * This watcher observes changes to the text and will shrink supported style ranges as necessary 17 * to provide the desired behavior. 18 */ 19class ComposeTextStyleWatcher : TextWatcher { 20 private val markerAnnotation = Annotation("text-formatting", "marker") 21 private var textSnapshotPriorToChange: CharSequence? = null 22 23 override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) { 24 if (s is Spannable) { 25 s.removeSpan(markerAnnotation) 26 } 27 28 textSnapshotPriorToChange = s.subSequence(start, start + count) 29 } 30 31 override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { 32 if (s is Spannable) { 33 s.removeSpan(markerAnnotation) 34 35 if (count > 0) { 36 s.setSpan(markerAnnotation, start, start + count, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) 37 } 38 } 39 } 40 41 override fun afterTextChanged(s: Editable) { 42 val editStart = s.getSpanStart(markerAnnotation) 43 val editEnd = s.getSpanEnd(markerAnnotation) 44 45 s.removeSpan(markerAnnotation) 46 47 try { 48 if (editStart < 0 || editEnd < 0 || editStart >= editEnd || (editStart == 0 && editEnd == s.length)) { 49 textSnapshotPriorToChange = null 50 return 51 } 52 53 val change = s.subSequence(editStart, editEnd) 54 if (change.isEmpty() || 55 textSnapshotPriorToChange == null || 56 (editEnd - editStart == 1 && !StringUtil.isVisuallyEmpty(change[0])) || 57 TextUtils.equals(textSnapshotPriorToChange, change) || 58 editEnd - editStart > 1 59 ) { 60 textSnapshotPriorToChange = null 61 return 62 } 63 textSnapshotPriorToChange = null 64 65 var newEnd = editStart 66 for (i in change.indices) { 67 if (StringUtil.isVisuallyEmpty(change[i])) { 68 newEnd = editStart + i 69 break 70 } 71 } 72 73 s.getSpans(editStart, editEnd, Object::class.java) 74 .filter { it.isSupportedStyle() } 75 .forEach { style -> 76 val styleStart = s.getSpanStart(style) 77 val styleEnd = s.getSpanEnd(style) 78 79 if (styleEnd == editEnd && styleStart < styleEnd) { 80 s.removeSpan(style) 81 s.setSpan(style, styleStart, newEnd, MessageStyler.SPAN_FLAGS) 82 } else if (styleStart >= styleEnd) { 83 s.removeSpan(style) 84 } 85 } 86 } finally { 87 s.getSpans(editStart, editEnd, Object::class.java) 88 .filter { it.isSupportedStyle() } 89 .forEach { style -> 90 val styleStart = s.getSpanStart(style) 91 val styleEnd = s.getSpanEnd(style) 92 if (styleEnd == styleStart || styleStart > styleEnd) { 93 s.removeSpan(style) 94 } 95 } 96 } 97 } 98}