mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-05-22 21:57:11 +00:00
Implement emoji autocompleting
This commit is contained in:
parent
48b04962c7
commit
d0da491922
5 changed files with 69 additions and 23 deletions
21
Habitica/res/layout/autocomplete_emoji.xml
Normal file
21
Habitica/res/layout/autocomplete_emoji.xml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="horizontal" android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="@dimen/spacing_medium"
|
||||
android:paddingBottom="@dimen/spacing_medium"
|
||||
android:paddingStart="@dimen/spacing_large"
|
||||
android:paddingEnd="@dimen/spacing_large">
|
||||
<net.pherth.android.emoji_library.EmojiTextView
|
||||
android:id="@+id/emoji_textview"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="30dp"
|
||||
android:layout_marginEnd="@dimen/spacing_large"
|
||||
android:layout_gravity="center_vertical"/>
|
||||
<TextView
|
||||
android:id="@+id/label"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="top" />
|
||||
</LinearLayout>
|
||||
|
|
@ -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" />
|
||||
<com.nex3z.flowlayout.FlowLayout
|
||||
android:id="@+id/buttons_wrapper"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
|||
|
|
@ -19,6 +19,6 @@ class FindUsernameResult {
|
|||
get() = if (username != null) "@$username" else null
|
||||
|
||||
override fun toString(): String {
|
||||
return authentication?.localAuthentication?.username ?: ""
|
||||
return "@${authentication?.localAuthentication?.username ?: ""}"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,21 +9,35 @@ import android.widget.Filterable
|
|||
import android.widget.TextView
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.data.SocialRepository
|
||||
import com.habitrpg.android.habitica.extensions.dpToPx
|
||||
import com.habitrpg.android.habitica.extensions.inflate
|
||||
import com.habitrpg.android.habitica.models.social.FindUsernameResult
|
||||
import com.habitrpg.android.habitica.ui.views.social.UsernameLabel
|
||||
import net.pherth.android.emoji_library.EmojiMap
|
||||
import net.pherth.android.emoji_library.EmojiParser
|
||||
import net.pherth.android.emoji_library.EmojiTextView
|
||||
|
||||
class AutocompleteAdapter(val context: Context, val socialRepository: SocialRepository, var autocompleteContext: String, var groupID: String?) : BaseAdapter(), Filterable {
|
||||
private var results: List<FindUsernameResult> = arrayListOf()
|
||||
private var userResults: List<FindUsernameResult> = arrayListOf()
|
||||
private var emojiResults: List<String> = 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<UsernameLabel>(R.id.display_name_view)
|
||||
displaynameView?.username = result.username
|
||||
displaynameView?.tier = result.contributor?.level ?: 0
|
||||
view?.findViewById<TextView>(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<UsernameLabel>(R.id.display_name_view)
|
||||
displaynameView?.username = result?.username
|
||||
displaynameView?.tier = result?.contributor?.level ?: 0
|
||||
view?.findViewById<TextView>(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<EmojiTextView>(R.id.emoji_textview)
|
||||
emojiTextView?.setEmojiconSize(24.dpToPx(context))
|
||||
emojiTextView?.text = EmojiParser.parseEmojis(result)
|
||||
view?.findViewById<TextView>(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
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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 "
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue