diff --git a/Habitica/res/layout/autocomplete_emoji.xml b/Habitica/res/layout/autocomplete_emoji.xml new file mode 100644 index 000000000..292a486d0 --- /dev/null +++ b/Habitica/res/layout/autocomplete_emoji.xml @@ -0,0 +1,21 @@ + + + + + \ No newline at end of file diff --git a/Habitica/res/layout/tavern_chat_item.xml b/Habitica/res/layout/tavern_chat_item.xml index 5cd60319f..3412740cf 100644 --- a/Habitica/res/layout/tavern_chat_item.xml +++ b/Habitica/res/layout/tavern_chat_item.xml @@ -101,7 +101,7 @@ android:layout_marginBottom="8dp" android:lineSpacingMultiplier="1.0" tools:text="This is the chat message" - android:textColor="@color/gray_10"/> + android:textColor="@color/gray_10" /> = arrayListOf() + private var userResults: List = arrayListOf() + private var emojiResults: List = arrayListOf() + private var isAutocompletingUsers = true override fun getFilter(): Filter { return object : Filter() { override fun performFiltering(constraint: CharSequence?): FilterResults { val filterResults = FilterResults() if (constraint != null && constraint.isNotEmpty()) { - results = socialRepository.findUsernames(constraint.toString(), autocompleteContext, groupID).blockingFirst(arrayListOf()) - filterResults.values = results - filterResults.count = results.size + if (constraint[0] == '@') { + isAutocompletingUsers = true + userResults = socialRepository.findUsernames(constraint.toString().drop(1), autocompleteContext, groupID).blockingFirst(arrayListOf()) + filterResults.values = userResults + filterResults.count = userResults.size + } else { + isAutocompletingUsers = false + emojiResults = EmojiMap.invertedEmojiMap.keys.filter { it.startsWith(constraint) } + filterResults.values = emojiResults + filterResults.count = emojiResults.size + } } return filterResults } @@ -39,25 +53,35 @@ class AutocompleteAdapter(val context: Context, val socialRepository: SocialRepo } override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View { - val view = parent?.inflate(R.layout.autocomplete_username) - val result = getItem(position) - val displaynameView = view?.findViewById(R.id.display_name_view) - displaynameView?.username = result.username - displaynameView?.tier = result.contributor?.level ?: 0 - view?.findViewById(R.id.username_view)?.text = result.formattedUsername - return view ?: View(context) + return if (isAutocompletingUsers) { + val view = parent?.inflate(R.layout.autocomplete_username) + val result = getItem(position) as? FindUsernameResult + val displaynameView = view?.findViewById(R.id.display_name_view) + displaynameView?.username = result?.username + displaynameView?.tier = result?.contributor?.level ?: 0 + view?.findViewById(R.id.username_view)?.text = result?.formattedUsername + view + } else { + val view = parent?.inflate(R.layout.autocomplete_emoji) + val result = getItem(position) as? String + val emojiTextView = view?.findViewById(R.id.emoji_textview) + emojiTextView?.setEmojiconSize(24.dpToPx(context)) + emojiTextView?.text = EmojiParser.parseEmojis(result) + view?.findViewById(R.id.label)?.text = result + view + } ?: View(context) } - override fun getItem(position: Int): FindUsernameResult { - return results[position] + override fun getItem(position: Int): Any { + return if (isAutocompletingUsers) userResults[position] else emojiResults[position] } override fun getItemId(position: Int): Long { - return getItem(position).id.hashCode().toLong() + return getItem(position).hashCode().toLong() } override fun getCount(): Int { - return results.size + return if (isAutocompletingUsers) userResults.size else emojiResults.size } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/helpers/ChatInputTokenizer.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/helpers/ChatInputTokenizer.kt index 2fc519a2e..39b9e0efd 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/helpers/ChatInputTokenizer.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/helpers/ChatInputTokenizer.kt @@ -11,15 +11,16 @@ class ChatInputTokenizer : MultiAutoCompleteTextView.Tokenizer { override fun findTokenStart(text: CharSequence, cursor: Int): Int { var i = cursor - while (i > 0 && text[i - 1] != '@') { + while (i > 0 && text[i - 1] != '@' && text[i - 1] != ':') { i-- } //Check if token really started with @, else we don't have a valid token - return if (i < 1 || text[i - 1] != '@') { + return if (i < 1 || (text[i - 1] != '@' && text[i - 1] != ':')) { cursor - } else i - + } else { + i - 1 + } } override fun findTokenEnd(text: CharSequence, cursor: Int): Int { @@ -48,12 +49,12 @@ class ChatInputTokenizer : MultiAutoCompleteTextView.Tokenizer { text } else { if (text is Spanned) { - val sp = SpannableString(text.toString() + " ") + val sp = SpannableString("$text ") TextUtils.copySpansFrom(text, 0, text.length, Any::class.java, sp, 0) sp } else { - text.toString() + " " + "$text " } } }