mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-08-01 19:50:53 +00:00
Make autocomplete work locally
This commit is contained in:
parent
e23f5e033d
commit
ccf873a359
10 changed files with 74 additions and 4 deletions
|
|
@ -16,5 +16,9 @@
|
|||
<key>spriteSubstitutions</key>
|
||||
<value>{}</value>
|
||||
</entry>
|
||||
<entry>
|
||||
<key>enableUsernameAutocomplete</key>
|
||||
<value>false</value>
|
||||
</entry>
|
||||
</defaultsMap>
|
||||
<!-- END xml_defaults -->
|
||||
|
|
@ -17,6 +17,7 @@ import com.amplitude.api.Amplitude
|
|||
import com.amplitude.api.Identify
|
||||
import com.facebook.drawee.backends.pipeline.Fresco
|
||||
import com.facebook.imagepipeline.core.ImagePipelineConfig
|
||||
import com.google.firebase.iid.FirebaseInstanceId
|
||||
import com.google.firebase.remoteconfig.FirebaseRemoteConfig
|
||||
import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings
|
||||
import com.habitrpg.android.habitica.api.HostConfig
|
||||
|
|
@ -82,6 +83,7 @@ abstract class HabiticaBaseApplication : MultiDexApplication() {
|
|||
setupRealm()
|
||||
setupDagger()
|
||||
setupRemoteConfig()
|
||||
setupNotifications()
|
||||
refWatcher = LeakCanary.install(this)
|
||||
setupInstabug()
|
||||
createBillingAndCheckout()
|
||||
|
|
@ -216,6 +218,23 @@ abstract class HabiticaBaseApplication : MultiDexApplication() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun setupNotifications() {
|
||||
FirebaseInstanceId.getInstance().instanceId.addOnCompleteListener { task ->
|
||||
if (!task.isSuccessful) {
|
||||
Log.w("Token", "getInstanceId failed", task.exception)
|
||||
return@addOnCompleteListener
|
||||
}
|
||||
|
||||
// Get new Instance ID token
|
||||
val token = task.result?.token
|
||||
|
||||
// Log and toast
|
||||
if (BuildConfig.DEBUG) {
|
||||
Log.d("Token", "Firebase Notification Token: $token")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
var component: AppComponent? = null
|
||||
|
|
|
|||
|
|
@ -6,10 +6,12 @@ import com.habitrpg.android.habitica.data.local.SocialLocalRepository
|
|||
import com.habitrpg.android.habitica.extensions.notNull
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.models.AchievementResult
|
||||
import com.habitrpg.android.habitica.models.auth.LocalAuthentication
|
||||
import com.habitrpg.android.habitica.models.inventory.Quest
|
||||
import com.habitrpg.android.habitica.models.members.Member
|
||||
import com.habitrpg.android.habitica.models.responses.PostChatMessageResult
|
||||
import com.habitrpg.android.habitica.models.social.*
|
||||
import com.habitrpg.android.habitica.models.user.Authentication
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
import io.reactivex.Flowable
|
||||
import io.reactivex.Single
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.habitrpg.android.habitica.data.local
|
|||
|
||||
import com.habitrpg.android.habitica.models.members.Member
|
||||
import com.habitrpg.android.habitica.models.social.ChatMessage
|
||||
import com.habitrpg.android.habitica.models.social.FindUsernameResult
|
||||
import com.habitrpg.android.habitica.models.social.Group
|
||||
import com.habitrpg.android.habitica.models.social.GroupMembership
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
|
|
|
|||
|
|
@ -46,4 +46,8 @@ class RemoteConfigManager {
|
|||
fun supportEmail(): String {
|
||||
return remoteConfig.getString("supportEmail")
|
||||
}
|
||||
|
||||
fun enableUsernameAutocomplete(): Boolean {
|
||||
return remoteConfig.getBoolean("enableUsernameAutocomplete")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.habitrpg.android.habitica.models.social
|
|||
import com.google.gson.annotations.SerializedName
|
||||
import com.habitrpg.android.habitica.models.user.Authentication
|
||||
import com.habitrpg.android.habitica.models.user.ContributorInfo
|
||||
import com.habitrpg.android.habitica.models.user.Profile
|
||||
import io.realm.annotations.PrimaryKey
|
||||
|
||||
class FindUsernameResult {
|
||||
|
|
@ -12,6 +13,7 @@ class FindUsernameResult {
|
|||
|
||||
var contributor: ContributorInfo? = null
|
||||
var authentication: Authentication? = null
|
||||
var profile: Profile? = null
|
||||
|
||||
val username: String?
|
||||
get() = authentication?.localAuthentication?.username
|
||||
|
|
|
|||
|
|
@ -228,6 +228,7 @@ class ChatFragment constructor() : BaseFragment(), SwipeRefreshLayout.OnRefreshL
|
|||
|
||||
private fun setChatMessages(chatMessages: RealmResults<ChatMessage>) {
|
||||
chatAdapter?.updateData(chatMessages)
|
||||
chatBarView.chatMessages = viewModel.socialRepository.getUnmanagedCopy(chatMessages)
|
||||
recyclerView.scrollToPosition(0)
|
||||
|
||||
viewModel.gotNewMessages = true
|
||||
|
|
|
|||
|
|
@ -290,6 +290,7 @@ class ChatListFragment : BaseFragment(), SwipeRefreshLayout.OnRefreshListener {
|
|||
|
||||
private fun setChatMessages(chatMessages: RealmResults<ChatMessage>) {
|
||||
chatAdapter?.updateData(chatMessages)
|
||||
chatBarView.chatMessages = socialRepository.getUnmanagedCopy(chatMessages)
|
||||
recyclerView.scrollToPosition(0)
|
||||
|
||||
gotNewMessages = true
|
||||
|
|
|
|||
|
|
@ -11,14 +11,21 @@ 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.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.models.auth.LocalAuthentication
|
||||
import com.habitrpg.android.habitica.models.social.ChatMessage
|
||||
import com.habitrpg.android.habitica.models.social.FindUsernameResult
|
||||
import com.habitrpg.android.habitica.models.user.Authentication
|
||||
import com.habitrpg.android.habitica.models.user.Profile
|
||||
import com.habitrpg.android.habitica.ui.views.social.UsernameLabel
|
||||
import io.reactivex.functions.Consumer
|
||||
import net.pherth.android.emoji_library.EmojiMap
|
||||
import net.pherth.android.emoji_library.EmojiParser
|
||||
import net.pherth.android.emoji_library.EmojiTextView
|
||||
import java.util.Date
|
||||
|
||||
class AutocompleteAdapter(val context: Context, val socialRepository: SocialRepository? = null, var autocompleteContext: String? = null, var groupID: String? = null) : BaseAdapter(), Filterable {
|
||||
class AutocompleteAdapter(val context: Context, val socialRepository: SocialRepository? = null, var autocompleteContext: String? = null, var groupID: String? = null, val remoteAutocomplete: Boolean = false) : BaseAdapter(), Filterable {
|
||||
var chatMessages: List<ChatMessage> = arrayListOf()
|
||||
private var userResults: List<FindUsernameResult> = arrayListOf()
|
||||
private var emojiResults: List<String> = arrayListOf()
|
||||
private var isAutocompletingUsers = true
|
||||
|
|
@ -29,7 +36,7 @@ class AutocompleteAdapter(val context: Context, val socialRepository: SocialRepo
|
|||
override fun performFiltering(constraint: CharSequence?): FilterResults {
|
||||
val filterResults = FilterResults()
|
||||
if (constraint != null && constraint.isNotEmpty()) {
|
||||
if (constraint[0] == '@' && constraint.length >= 3 && socialRepository != null) {
|
||||
if (constraint[0] == '@' && constraint.length >= 3 && socialRepository != null && remoteAutocomplete) {
|
||||
if (Date().time - lastAutocomplete > 2000) {
|
||||
lastAutocomplete = Date().time
|
||||
userResults = arrayListOf()
|
||||
|
|
@ -43,6 +50,24 @@ class AutocompleteAdapter(val context: Context, val socialRepository: SocialRepo
|
|||
filterResults.values = userResults
|
||||
filterResults.count = userResults.size
|
||||
}
|
||||
} else if (constraint[0] == '@') {
|
||||
lastAutocomplete = Date().time
|
||||
isAutocompletingUsers = true
|
||||
userResults = chatMessages.distinctBy {
|
||||
it.username
|
||||
}.filter { it.username?.startsWith(constraint.toString().drop(1)) ?: false }.map {message ->
|
||||
val result = FindUsernameResult()
|
||||
result.authentication = Authentication()
|
||||
result.authentication?.localAuthentication = LocalAuthentication()
|
||||
result.authentication?.localAuthentication?.userID = message.uuid
|
||||
result.authentication?.localAuthentication?.username = message.username
|
||||
result.contributor = message.contributor
|
||||
result.profile = Profile()
|
||||
result.profile?.name = message.user
|
||||
result
|
||||
}
|
||||
filterResults.values = userResults
|
||||
filterResults.count = userResults.size
|
||||
} else if (constraint[0] == ':') {
|
||||
isAutocompletingUsers = false
|
||||
emojiResults = EmojiMap.invertedEmojiMap.keys.filter { it.startsWith(constraint) }
|
||||
|
|
@ -68,7 +93,7 @@ class AutocompleteAdapter(val context: Context, val socialRepository: SocialRepo
|
|||
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?.username = result?.profile?.name
|
||||
displaynameView?.tier = result?.contributor?.level ?: 0
|
||||
view?.findViewById<TextView>(R.id.username_view)?.text = result?.formattedUsername
|
||||
view
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ import androidx.core.view.updateLayoutParams
|
|||
import com.habitrpg.android.habitica.HabiticaBaseApplication
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.data.SocialRepository
|
||||
import com.habitrpg.android.habitica.helpers.RemoteConfigManager
|
||||
import com.habitrpg.android.habitica.models.social.ChatMessage
|
||||
import com.habitrpg.android.habitica.ui.helpers.AutocompleteAdapter
|
||||
import com.habitrpg.android.habitica.ui.helpers.AutocompleteTokenizer
|
||||
import com.habitrpg.android.habitica.ui.helpers.NavbarUtils
|
||||
|
|
@ -25,6 +27,9 @@ class ChatBarView : FrameLayout {
|
|||
@Inject
|
||||
lateinit var socialRepository: SocialRepository
|
||||
|
||||
@Inject
|
||||
lateinit var remoteConfig: RemoteConfigManager
|
||||
|
||||
private val sendButton: ImageButton by bindView(R.id.sendButton)
|
||||
private val chatEditText: MultiAutoCompleteTextView by bindView(R.id.chatEditText)
|
||||
private val textIndicator: TextView by bindView(R.id.text_indicator)
|
||||
|
|
@ -32,6 +37,12 @@ class ChatBarView : FrameLayout {
|
|||
private val spacing: Space by bindView(R.id.spacing)
|
||||
private var navBarAccountedHeightCalculated = false
|
||||
|
||||
var chatMessages: List<ChatMessage>
|
||||
get() = autocompleteAdapter?.chatMessages ?: listOf()
|
||||
set(value) {
|
||||
autocompleteAdapter?.chatMessages = value
|
||||
}
|
||||
|
||||
internal var maxChatLength = 3000L
|
||||
|
||||
var sendAction: ((String) -> Unit)? = null
|
||||
|
|
@ -78,7 +89,7 @@ class ChatBarView : FrameLayout {
|
|||
|
||||
resizeForDrawingUnderNavbar()
|
||||
|
||||
autocompleteAdapter = AutocompleteAdapter(context, socialRepository, autocompleteContext, groupID)
|
||||
autocompleteAdapter = AutocompleteAdapter(context, socialRepository, autocompleteContext, groupID, remoteConfig.enableUsernameAutocomplete())
|
||||
chatEditText.setAdapter(autocompleteAdapter)
|
||||
chatEditText.threshold = 2
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue