From 4feac1cb50dfb1b638f7e7e678b9276e0b99c695 Mon Sep 17 00:00:00 2001 From: rapterjet2004 Date: Mon, 10 Feb 2025 12:18:26 -0600 Subject: [PATCH 1/4] found the error Signed-off-by: rapterjet2004 --- .../talk/chat/MessageInputFragment.kt | 18 +++++++++++++----- .../com/nextcloud/talk/utils/CharPolicy.java | 4 +++- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/chat/MessageInputFragment.kt b/app/src/main/java/com/nextcloud/talk/chat/MessageInputFragment.kt index 14607a21057..9039346dcd5 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/MessageInputFragment.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/MessageInputFragment.kt @@ -366,15 +366,23 @@ class MessageInputFragment : Fragment() { var mentionSpan: Spans.MentionChipSpan for (i in mentionSpans.indices) { mentionSpan = mentionSpans[i] + val start = editable.getSpanStart(mentionSpan) + val end = editable.getSpanEnd(mentionSpan) + Log.d("Julius", "S:$start E:$end") if (start >= editable.getSpanStart(mentionSpan) && start < editable.getSpanEnd(mentionSpan) ) { - if (editable.subSequence( - editable.getSpanStart(mentionSpan), - editable.getSpanEnd(mentionSpan) - ).toString().trim { it <= ' ' } != mentionSpan.label + val what = editable.subSequence( + editable.getSpanStart(mentionSpan), + editable.getSpanEnd(mentionSpan) + ).toString() + + if (what.trim { it <= ' ' } != mentionSpan.label ) { - editable.removeSpan(mentionSpan) + Log.d("Julius", "What: $what") + Log.d("Julius", "MentionSpan removed: $mentionSpan") + // FIXME error here- I knew it I was right, but why? + // editable.removeSpan(mentionSpan) } } } diff --git a/app/src/main/java/com/nextcloud/talk/utils/CharPolicy.java b/app/src/main/java/com/nextcloud/talk/utils/CharPolicy.java index add1d48d768..baedde6d653 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/CharPolicy.java +++ b/app/src/main/java/com/nextcloud/talk/utils/CharPolicy.java @@ -9,12 +9,14 @@ import android.text.Spannable; import android.text.Spanned; -import androidx.annotation.Nullable; + import com.otaliastudios.autocomplete.AutocompletePolicy; import java.util.regex.Matcher; import java.util.regex.Pattern; +import androidx.annotation.Nullable; + public class CharPolicy implements AutocompletePolicy { private final char character; From 2c3448f3282fab4bfa36ef74ff3830852d1cf825 Mon Sep 17 00:00:00 2001 From: rapterjet2004 Date: Tue, 11 Feb 2025 15:24:27 -0600 Subject: [PATCH 2/4] detect the error, but how to replace? Signed-off-by: rapterjet2004 --- .../talk/chat/MessageInputFragment.kt | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/chat/MessageInputFragment.kt b/app/src/main/java/com/nextcloud/talk/chat/MessageInputFragment.kt index 9039346dcd5..e554a6435e0 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/MessageInputFragment.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/MessageInputFragment.kt @@ -366,23 +366,20 @@ class MessageInputFragment : Fragment() { var mentionSpan: Spans.MentionChipSpan for (i in mentionSpans.indices) { mentionSpan = mentionSpans[i] - val start = editable.getSpanStart(mentionSpan) - val end = editable.getSpanEnd(mentionSpan) - Log.d("Julius", "S:$start E:$end") + + val what = editable.subSequence( + editable.getSpanStart(mentionSpan), + editable.getSpanEnd(mentionSpan) + ).toString().trim { it <= ' ' } + val error = what.length > mentionSpan.label.length + if (start >= editable.getSpanStart(mentionSpan) && - start < editable.getSpanEnd(mentionSpan) + start < editable.getSpanEnd(mentionSpan) && + what != mentionSpan.label ) { - val what = editable.subSequence( - editable.getSpanStart(mentionSpan), - editable.getSpanEnd(mentionSpan) - ).toString() - - if (what.trim { it <= ' ' } != mentionSpan.label - ) { - Log.d("Julius", "What: $what") - Log.d("Julius", "MentionSpan removed: $mentionSpan") - // FIXME error here- I knew it I was right, but why? - // editable.removeSpan(mentionSpan) + editable.removeSpan(mentionSpan) + if (error) { + Log.d("Julius", "Error: Fix mention") } } } From b72c829cd2547569b373c0a609087cd99199faee Mon Sep 17 00:00:00 2001 From: rapterjet2004 Date: Wed, 12 Feb 2025 11:44:42 -0600 Subject: [PATCH 3/4] moved some code around Signed-off-by: rapterjet2004 --- .../talk/chat/MessageInputFragment.kt | 52 ++++++++----------- 1 file changed, 23 insertions(+), 29 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/chat/MessageInputFragment.kt b/app/src/main/java/com/nextcloud/talk/chat/MessageInputFragment.kt index e554a6435e0..853a173a95a 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/MessageInputFragment.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/MessageInputFragment.kt @@ -156,10 +156,6 @@ class MessageInputFragment : Fragment() { saveState() } - override fun onResume() { - super.onResume() - } - override fun onDestroyView() { super.onDestroyView() if (mentionAutocomplete != null && mentionAutocomplete!!.isPopupShowing) { @@ -356,34 +352,32 @@ class MessageInputFragment : Fragment() { } val editable = binding.fragmentMessageInputView.inputEditText?.editableText + if (editable != null && binding.fragmentMessageInputView.inputEditText != null) return - if (editable != null && binding.fragmentMessageInputView.inputEditText != null) { - val mentionSpans = editable.getSpans( - 0, - binding.fragmentMessageInputView.inputEditText!!.length(), - Spans.MentionChipSpan::class.java - ) - var mentionSpan: Spans.MentionChipSpan - for (i in mentionSpans.indices) { - mentionSpan = mentionSpans[i] - - val what = editable.subSequence( - editable.getSpanStart(mentionSpan), - editable.getSpanEnd(mentionSpan) - ).toString().trim { it <= ' ' } - val error = what.length > mentionSpan.label.length - - if (start >= editable.getSpanStart(mentionSpan) && - start < editable.getSpanEnd(mentionSpan) && - what != mentionSpan.label - ) { - editable.removeSpan(mentionSpan) - if (error) { - Log.d("Julius", "Error: Fix mention") - } - } + val mentionSpans = editable!!.getSpans( + 0, + binding.fragmentMessageInputView.inputEditText!!.length(), + Spans.MentionChipSpan::class.java + ) + var mentionSpan: Spans.MentionChipSpan + for (i in mentionSpans.indices) { + mentionSpan = mentionSpans[i] + + val spStart = editable.getSpanStart(mentionSpan) + val spEnd = editable.getSpanEnd(mentionSpan) + + val what = editable.subSequence(spStart, spEnd).toString().trim { it <= ' ' } + val error = what.length > mentionSpan.label.length + + if (start in spStart..< spEnd && what != mentionSpan.label) { + editable.removeSpan(mentionSpan) + } + + if (error) { + Log.d("Julius", "Error: Fix mention") } } + } override fun afterTextChanged(s: Editable) { From cc8e51a8f4ffa868b8ab017994518b473f180ecf Mon Sep 17 00:00:00 2001 From: rapterjet2004 Date: Thu, 13 Feb 2025 11:18:04 -0600 Subject: [PATCH 4/4] Got the replacement logic down, not perfect fix but a workaround. --- .../talk/chat/MessageInputFragment.kt | 41 ++++++++++++++----- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/chat/MessageInputFragment.kt b/app/src/main/java/com/nextcloud/talk/chat/MessageInputFragment.kt index 853a173a95a..e7c6cd6a74d 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/MessageInputFragment.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/MessageInputFragment.kt @@ -7,7 +7,6 @@ package com.nextcloud.talk.chat -import android.content.res.Resources import android.graphics.drawable.ColorDrawable import android.graphics.drawable.Drawable import android.os.Build @@ -16,6 +15,7 @@ import android.os.CountDownTimer import android.os.SystemClock import android.text.Editable import android.text.InputFilter +import android.text.Spanned import android.text.TextUtils import android.text.TextWatcher import android.util.Log @@ -85,7 +85,7 @@ import kotlinx.coroutines.launch import java.util.Objects import javax.inject.Inject -@Suppress("LongParameterList", "TooManyFunctions") +@Suppress("LongParameterList", "TooManyFunctions", "LargeClass") @AutoInjector(NextcloudTalkApplication::class) class MessageInputFragment : Fragment() { @@ -108,6 +108,19 @@ class MessageInputFragment : Fragment() { private const val CONNECTION_ESTABLISHED_ANIM_DURATION: Long = 3000 private const val FULLY_OPAQUE: Float = 1.0f private const val FULLY_TRANSPARENT: Float = 0.0f + + /** + * Note: Start index guaranteed >= 0 if correct, -1 if error + * @return `Pair(start index + 1, end index) + */ + private fun String.getStartAndEndIndexOf(substring: String): Pair { + val index = this.indexOf(substring) + if (index < 0) return Pair(-1, -1) + + val start = kotlin.math.max(0, index + 1) + val end = start + substring.length + return Pair(start, end) + } } @Inject @@ -344,7 +357,7 @@ class MessageInputFragment : Fragment() { if (s.length >= lengthFilter) { binding.fragmentMessageInputView.inputEditText?.error = String.format( - Objects.requireNonNull(resources).getString(R.string.nc_limit_hit), + Objects.requireNonNull(resources).getString(R.string.nc_limit_hit), lengthFilter.toString() ) } else { @@ -352,9 +365,9 @@ class MessageInputFragment : Fragment() { } val editable = binding.fragmentMessageInputView.inputEditText?.editableText - if (editable != null && binding.fragmentMessageInputView.inputEditText != null) return + if (editable == null || binding.fragmentMessageInputView.inputEditText == null) return - val mentionSpans = editable!!.getSpans( + val mentionSpans = editable.getSpans( 0, binding.fragmentMessageInputView.inputEditText!!.length(), Spans.MentionChipSpan::class.java @@ -365,19 +378,25 @@ class MessageInputFragment : Fragment() { val spStart = editable.getSpanStart(mentionSpan) val spEnd = editable.getSpanEnd(mentionSpan) + val spanRangeStr = editable.subSequence(spStart, spEnd).toString().trim { it <= ' ' } + val error = spanRangeStr.length > mentionSpan.label.length - val what = editable.subSequence(spStart, spEnd).toString().trim { it <= ' ' } - val error = what.length > mentionSpan.label.length - - if (start in spStart..< spEnd && what != mentionSpan.label) { + if (start in spStart..